run-dmcp 0.3.0 → 0.5.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.
Files changed (49) hide show
  1. package/README.md +19 -5
  2. package/dist/bin/run-dmcp.js +1 -1
  3. package/dist/index.d.ts +0 -1
  4. package/dist/index.js +7 -1
  5. package/dist/mcp-server.d.ts +5 -1
  6. package/dist/mcp-server.js +5 -1
  7. package/dist/register/batch.js +11 -10
  8. package/dist/register/character.js +16 -16
  9. package/dist/register/core.js +128 -111
  10. package/dist/register/display.js +42 -41
  11. package/dist/register/resolve.js +4 -1
  12. package/dist/register/world.js +13 -13
  13. package/dist/rpg/index.d.ts +0 -16
  14. package/dist/rpg/index.js +4 -22
  15. package/dist/rpg/register/batch.js +3 -3
  16. package/dist/rpg/server.d.ts +16 -0
  17. package/dist/rpg/server.js +22 -0
  18. package/dist/schemas/index.d.ts +62 -62
  19. package/dist/schemas/index.js +91 -72
  20. package/dist/server.d.ts +1 -0
  21. package/dist/server.js +20 -0
  22. package/dist/utils/output-schemas.d.ts +58 -58
  23. package/dist/utils/validation.d.ts +31 -2
  24. package/dist/utils/validation.js +67 -10
  25. package/package.json +9 -1
  26. package/dist/register/abilities.d.ts +0 -2
  27. package/dist/register/abilities.js +0 -165
  28. package/dist/register/combat.d.ts +0 -2
  29. package/dist/register/combat.js +0 -207
  30. package/dist/register/mcp-prompts.d.ts +0 -2
  31. package/dist/register/mcp-prompts.js +0 -684
  32. package/dist/register/quests.d.ts +0 -2
  33. package/dist/register/quests.js +0 -118
  34. package/dist/register/status.d.ts +0 -2
  35. package/dist/register/status.js +0 -130
  36. package/dist/register/tables.d.ts +0 -2
  37. package/dist/register/tables.js +0 -146
  38. package/dist/tools/ability.d.ts +0 -48
  39. package/dist/tools/ability.js +0 -238
  40. package/dist/tools/combat.d.ts +0 -13
  41. package/dist/tools/combat.js +0 -195
  42. package/dist/tools/dice.d.ts +0 -23
  43. package/dist/tools/dice.js +0 -111
  44. package/dist/tools/quest.d.ts +0 -34
  45. package/dist/tools/quest.js +0 -164
  46. package/dist/tools/status.d.ts +0 -36
  47. package/dist/tools/status.js +0 -218
  48. package/dist/tools/tables.d.ts +0 -33
  49. package/dist/tools/tables.js +0 -209
@@ -1,121 +1,140 @@
1
+ // Reusable Zod schemas, shared by the register modules.
2
+ //
3
+ // EVERY string here is bounded, and this file is where most of the engine's
4
+ // bounds actually live: `imageGenSchema` alone is accepted by seven tools, so
5
+ // one unbounded leaf in it was seven unbounded declarations in the published
6
+ // contract (issue #29 -- 698 of them, against 348 hand-written `.max()` calls
7
+ // spread across the register modules). Bounds belong in the shared schema, not
8
+ // at each call site, for the same reason the schema itself is shared.
9
+ //
10
+ // The tiers come from `validatedSchemas` (../utils/validation.ts) and nowhere
11
+ // else: `.token` for a short descriptor, `.description` for free text a model
12
+ // writes prose into, `.embeddedData` for inline base64. Reach for one of those
13
+ // rather than hand-rolling `z.string().max(...)` -- inlining the bound at each
14
+ // site is exactly how 698 of them came to be forgotten. Each access hands back
15
+ // a FRESH schema instance, deliberately; that file's comment says why, and it
16
+ // is the difference between publishing a declaration and publishing a `$ref`.
1
17
  import { z } from "zod";
18
+ import { LIMITS, validatedSchemas } from "../utils/validation.js";
2
19
  // Reusable Zod schemas for image generation
3
20
  export const subjectDescriptionSchema = z.object({
4
21
  type: z.enum(["character", "location", "item", "scene"]),
5
- primaryDescription: z.string(),
22
+ primaryDescription: validatedSchemas.description,
6
23
  physicalTraits: z.object({
7
- age: z.string().optional(),
8
- gender: z.string().optional(),
9
- bodyType: z.string().optional(),
10
- height: z.string().optional(),
11
- skinTone: z.string().optional(),
12
- hairColor: z.string().optional(),
13
- hairStyle: z.string().optional(),
14
- eyeColor: z.string().optional(),
15
- facialFeatures: z.string().optional(),
16
- distinguishingMarks: z.array(z.string()).optional(),
24
+ age: validatedSchemas.token.optional(),
25
+ gender: validatedSchemas.token.optional(),
26
+ bodyType: validatedSchemas.token.optional(),
27
+ height: validatedSchemas.token.optional(),
28
+ skinTone: validatedSchemas.token.optional(),
29
+ hairColor: validatedSchemas.token.optional(),
30
+ hairStyle: validatedSchemas.token.optional(),
31
+ eyeColor: validatedSchemas.token.optional(),
32
+ facialFeatures: validatedSchemas.description.optional(),
33
+ distinguishingMarks: validatedSchemas.stringArray.optional(),
17
34
  }).optional(),
18
35
  attire: z.object({
19
- description: z.string(),
20
- colors: z.array(z.string()).optional(),
21
- materials: z.array(z.string()).optional(),
22
- accessories: z.array(z.string()).optional(),
36
+ description: validatedSchemas.description,
37
+ colors: validatedSchemas.stringArray.optional(),
38
+ materials: validatedSchemas.stringArray.optional(),
39
+ accessories: validatedSchemas.stringArray.optional(),
23
40
  }).optional(),
24
41
  environment: z.object({
25
- setting: z.string(),
26
- timeOfDay: z.string().optional(),
27
- weather: z.string().optional(),
28
- lighting: z.string().optional(),
29
- architecture: z.string().optional(),
30
- vegetation: z.string().optional(),
31
- notableFeatures: z.array(z.string()).optional(),
42
+ setting: validatedSchemas.description,
43
+ timeOfDay: validatedSchemas.token.optional(),
44
+ weather: validatedSchemas.token.optional(),
45
+ lighting: validatedSchemas.token.optional(),
46
+ architecture: validatedSchemas.token.optional(),
47
+ vegetation: validatedSchemas.token.optional(),
48
+ notableFeatures: validatedSchemas.stringArray.optional(),
32
49
  }).optional(),
33
50
  objectDetails: z.object({
34
- material: z.string().optional(),
35
- size: z.string().optional(),
36
- condition: z.string().optional(),
37
- glowOrEffects: z.string().optional(),
51
+ material: validatedSchemas.token.optional(),
52
+ size: validatedSchemas.token.optional(),
53
+ condition: validatedSchemas.token.optional(),
54
+ glowOrEffects: validatedSchemas.description.optional(),
38
55
  }).optional(),
39
- pose: z.string().optional(),
40
- expression: z.string().optional(),
41
- action: z.string().optional(),
56
+ pose: validatedSchemas.description.optional(),
57
+ expression: validatedSchemas.description.optional(),
58
+ action: validatedSchemas.description.optional(),
42
59
  });
43
60
  export const styleDescriptionSchema = z.object({
44
- artisticStyle: z.string(),
45
- genre: z.string(),
46
- mood: z.string(),
47
- colorScheme: z.string().optional(),
48
- influences: z.array(z.string()).optional(),
49
- qualityTags: z.array(z.string()).optional(),
50
- negativeElements: z.array(z.string()).optional(),
61
+ artisticStyle: validatedSchemas.description,
62
+ genre: validatedSchemas.token,
63
+ mood: validatedSchemas.token,
64
+ colorScheme: validatedSchemas.token.optional(),
65
+ influences: validatedSchemas.stringArray.optional(),
66
+ qualityTags: validatedSchemas.stringArray.optional(),
67
+ negativeElements: validatedSchemas.stringArray.optional(),
51
68
  });
52
69
  export const compositionDescriptionSchema = z.object({
53
- framing: z.string(),
54
- cameraAngle: z.string().optional(),
55
- aspectRatio: z.string().optional(),
56
- focusPoint: z.string().optional(),
57
- background: z.string().optional(),
58
- depth: z.string().optional(),
70
+ framing: validatedSchemas.description,
71
+ cameraAngle: validatedSchemas.token.optional(),
72
+ aspectRatio: validatedSchemas.token.optional(),
73
+ focusPoint: validatedSchemas.description.optional(),
74
+ background: validatedSchemas.description.optional(),
75
+ depth: validatedSchemas.token.optional(),
59
76
  });
60
77
  export const comfyUIPromptSchema = z.object({
61
- positive: z.string(),
62
- negative: z.string(),
63
- checkpoint: z.string().optional(),
78
+ positive: validatedSchemas.description,
79
+ negative: validatedSchemas.description,
80
+ checkpoint: validatedSchemas.token.optional(),
64
81
  loras: z.array(z.object({
65
- name: z.string(),
82
+ name: validatedSchemas.name,
66
83
  weight: z.number(),
67
- })).optional(),
84
+ })).max(LIMITS.ARRAY_MAX).optional(),
68
85
  samplerSettings: z.object({
69
- sampler: z.string().optional(),
70
- scheduler: z.string().optional(),
86
+ sampler: validatedSchemas.token.optional(),
87
+ scheduler: validatedSchemas.token.optional(),
71
88
  steps: z.number().optional(),
72
89
  cfg: z.number().optional(),
73
90
  }).optional(),
74
91
  });
75
92
  export const generatedImageSchema = z.object({
76
- id: z.string(),
77
- tool: z.string(),
78
- prompt: z.string(),
79
- url: z.string().optional(),
80
- base64: z.string().optional(),
93
+ id: validatedSchemas.id,
94
+ tool: validatedSchemas.token,
95
+ prompt: validatedSchemas.description,
96
+ // A URL, including a `data:` one. Over DESCRIPTION_MAX it is not an address,
97
+ // it is a payload, and `base64` below is the field for those.
98
+ url: validatedSchemas.description.optional(),
99
+ base64: validatedSchemas.embeddedData.optional(),
81
100
  seed: z.number().optional(),
82
- timestamp: z.string(),
83
- metadata: z.record(z.string(), z.unknown()).optional(),
101
+ timestamp: validatedSchemas.token,
102
+ metadata: z.record(validatedSchemas.token, z.unknown()).optional(),
84
103
  });
85
104
  export const imageGenSchema = z.object({
86
105
  subject: subjectDescriptionSchema,
87
106
  style: styleDescriptionSchema,
88
107
  composition: compositionDescriptionSchema,
89
108
  prompts: z.object({
90
- generic: z.string().optional(),
91
- sdxl: z.string().optional(),
92
- dalle: z.string().optional(),
93
- midjourney: z.string().optional(),
94
- flux: z.string().optional(),
109
+ generic: validatedSchemas.description.optional(),
110
+ sdxl: validatedSchemas.description.optional(),
111
+ dalle: validatedSchemas.description.optional(),
112
+ midjourney: validatedSchemas.description.optional(),
113
+ flux: validatedSchemas.description.optional(),
95
114
  comfyui: comfyUIPromptSchema.optional(),
96
115
  }).optional(),
97
- generations: z.array(generatedImageSchema).optional(),
116
+ generations: z.array(generatedImageSchema).max(LIMITS.ARRAY_MAX).optional(),
98
117
  consistency: z.object({
99
- characterRef: z.string().optional(),
100
- seedImage: z.string().optional(),
101
- colorPalette: z.array(z.string()).optional(),
102
- styleRef: z.string().optional(),
118
+ characterRef: validatedSchemas.description.optional(),
119
+ seedImage: validatedSchemas.description.optional(),
120
+ colorPalette: validatedSchemas.stringArray.optional(),
121
+ styleRef: validatedSchemas.description.optional(),
103
122
  }).optional(),
104
123
  }).describe("Image generation metadata for visual representation");
105
124
  // Voice schema for characters
106
125
  export const voiceSchema = z.object({
107
126
  pitch: z.enum(["very_low", "low", "medium", "high", "very_high"]).describe("Voice pitch"),
108
127
  speed: z.enum(["very_slow", "slow", "medium", "fast", "very_fast"]).describe("Speaking speed"),
109
- tone: z.string().describe("Voice tone (e.g., 'gravelly', 'melodic', 'nasal', 'breathy')"),
110
- accent: z.string().optional().describe("Accent (e.g., 'Scottish', 'French', 'Brooklyn')"),
111
- quirks: z.array(z.string()).optional().describe("Speech quirks (e.g., 'stutters when nervous')"),
112
- description: z.string().optional().describe("Free-form voice description for more nuance"),
128
+ tone: validatedSchemas.token.describe("Voice tone (e.g., 'gravelly', 'melodic', 'nasal', 'breathy')"),
129
+ accent: validatedSchemas.token.optional().describe("Accent (e.g., 'Scottish', 'French', 'Brooklyn')"),
130
+ quirks: validatedSchemas.stringArray.optional().describe("Speech quirks (e.g., 'stutters when nervous')"),
131
+ description: validatedSchemas.description.optional().describe("Free-form voice description for more nuance"),
113
132
  });
114
133
  // Random table entry schema
115
134
  export const tableEntrySchema = z.object({
116
135
  minRoll: z.number().optional().describe("Minimum roll to get this result (for ranged tables)"),
117
136
  maxRoll: z.number().optional().describe("Maximum roll for this result"),
118
137
  weight: z.number().optional().describe("Weight for weighted random selection"),
119
- result: z.string().describe("The result text"),
120
- effects: z.record(z.unknown()).optional().describe("Optional structured effects"),
138
+ result: validatedSchemas.description.describe("The result text"),
139
+ effects: z.record(validatedSchemas.token, z.unknown()).optional().describe("Optional structured effects"),
121
140
  });
@@ -0,0 +1 @@
1
+ export { createCoreMcpServer, SERVER_NAME, SERVER_VERSION } from "./mcp-server.js";
package/dist/server.js ADDED
@@ -0,0 +1,20 @@
1
+ // The core assembly: the MCP server built from the core's tools.
2
+ //
3
+ // This is a SEPARATE entry point (`run-dmcp/server`) from the core library
4
+ // (`run-dmcp`, src/index.ts) for one reason, and it is a cost. Building a
5
+ // server means loading the MCP SDK and twenty-one register modules; wanting
6
+ // `LIMITS` or `createGame` does not. While these lived on the same entry,
7
+ // every consumer paid for both -- 97.4ms per process against 46.8ms for the
8
+ // mechanism alone, measured cold at 0.3.0 over nine spawns, on a consumer
9
+ // that spawns a fresh process per turn and never calls this function.
10
+ //
11
+ // The split is a move, not a change: `createCoreMcpServer` is the same
12
+ // function with the same options, reached by a different specifier.
13
+ // src/__tests__/assemblyBoundary.test.ts asserts that it stays reachable
14
+ // from here, and unreachable from there.
15
+ //
16
+ // Importing this module must still do nothing to the machine -- the rule
17
+ // src/index.ts's header states applies to every library entry this package
18
+ // publishes, and src/__tests__/entrypoints.test.ts holds it. Starting things
19
+ // is src/bin/run-dmcp.ts.
20
+ export { createCoreMcpServer, SERVER_NAME, SERVER_VERSION } from "./mcp-server.js";