@plitzi/sdk-server 0.32.9 → 0.32.11

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 (83) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/core/http/dispatcher.js +45 -9
  3. package/dist/core/services/mcp.js +9 -7
  4. package/dist/helpers/serverLog.js +33 -0
  5. package/dist/index.js +2 -1
  6. package/dist/mcp.d.ts +2 -0
  7. package/dist/mcp.js +7 -0
  8. package/dist/modules/mcp/apps/example/view.tsx +70 -0
  9. package/dist/modules/mcp/apps/index.js +12 -0
  10. package/dist/modules/mcp/apps/render/index.js +16 -0
  11. package/dist/modules/mcp/apps/render/view.tsx +108 -0
  12. package/dist/modules/mcp/apps/shared/bundle.js +22 -0
  13. package/dist/modules/mcp/apps/shared/page.js +23 -0
  14. package/dist/modules/mcp/apps/shared/registerApp.js +27 -0
  15. package/dist/modules/mcp/apps/shared/resolve.js +5 -0
  16. package/dist/modules/mcp/apps/shared/shell.ejs +37 -0
  17. package/dist/modules/mcp/apps/shared/zodEnglishOnly.js +23 -0
  18. package/dist/modules/mcp/handler.js +8 -6
  19. package/dist/modules/mcp/helpers/log.js +20 -10
  20. package/dist/modules/mcp/resources/register.js +11 -5
  21. package/dist/modules/mcp/resources/renderGuide.js +17 -7
  22. package/dist/modules/mcp/server.js +21 -12
  23. package/dist/modules/mcp/tools/apply/index.js +1 -1
  24. package/dist/modules/mcp/tools/render.js +3 -3
  25. package/dist/modules/ssr/registerExternalPlugins.js +1 -1
  26. package/dist/modules/ssr/template.js +1 -1
  27. package/dist/plugins/compile.js +1 -1
  28. package/dist/plugins/copy.js +1 -1
  29. package/dist/plugins/manager.js +3 -1
  30. package/dist/plugins/validate.js +23 -0
  31. package/dist/src/core/http/dispatcher.test.d.ts +1 -0
  32. package/dist/src/core/http/types.d.ts +3 -0
  33. package/dist/src/core/requestParser.d.ts +3 -0
  34. package/dist/src/helpers/buildResponseHelpers.d.ts +2 -0
  35. package/dist/src/helpers/serverLog.d.ts +10 -0
  36. package/dist/src/index.d.ts +2 -1
  37. package/dist/src/mcp.d.ts +14 -0
  38. package/dist/src/modules/mcp/apps/apps.test.d.ts +1 -0
  39. package/dist/src/modules/mcp/apps/example/index.d.ts +8 -0
  40. package/dist/src/modules/mcp/apps/example/view.d.ts +1 -0
  41. package/dist/src/modules/mcp/apps/index.d.ts +8 -0
  42. package/dist/src/modules/mcp/apps/render/index.d.ts +3 -0
  43. package/dist/src/modules/mcp/apps/render/view.d.ts +1 -0
  44. package/dist/src/modules/mcp/apps/shared/bundle.d.ts +1 -0
  45. package/dist/src/modules/mcp/apps/shared/index.d.ts +2 -0
  46. package/dist/src/modules/mcp/apps/shared/page.d.ts +2 -0
  47. package/dist/src/modules/mcp/apps/shared/registerApp.d.ts +5 -0
  48. package/dist/src/modules/mcp/apps/shared/resolve.d.ts +1 -0
  49. package/dist/src/modules/mcp/apps/shared/zodEnglishOnly.d.ts +4 -0
  50. package/dist/src/modules/mcp/e2e/connector.test.d.ts +1 -0
  51. package/dist/src/modules/mcp/e2e/host.test.d.ts +1 -0
  52. package/dist/src/modules/mcp/e2e/index.d.ts +6 -0
  53. package/dist/src/modules/mcp/e2e/mcpEndpoint.d.ts +20 -0
  54. package/dist/src/modules/mcp/e2e/postMessageChannel.d.ts +22 -0
  55. package/dist/src/modules/mcp/e2e/renderingHost.d.ts +14 -0
  56. package/dist/src/modules/mcp/handler.d.ts +11 -7
  57. package/dist/src/modules/mcp/helpers/log.d.ts +3 -3
  58. package/dist/src/modules/mcp/index.d.ts +1 -0
  59. package/dist/src/modules/mcp/resources/register.d.ts +1 -1
  60. package/dist/src/modules/mcp/resources/renderGuide.d.ts +3 -2
  61. package/dist/src/modules/mcp/server.d.ts +4 -12
  62. package/dist/src/modules/mcp/tools/apply/index.d.ts +3 -3
  63. package/dist/src/modules/mcp/tools/operations/index.d.ts +6 -6
  64. package/dist/src/modules/mcp/tools/operations/schema/operations.d.ts +1 -1
  65. package/dist/src/modules/mcp/tools/operations/schema/settings/patchSettings.d.ts +1 -1
  66. package/dist/src/modules/mcp/tools/operations/style/operations.d.ts +2 -2
  67. package/dist/src/modules/mcp/tools/operations/style/shared.d.ts +1 -1
  68. package/dist/src/modules/mcp/tools/operations/style/variables/deleteStyleVariable.d.ts +1 -1
  69. package/dist/src/modules/mcp/tools/operations/style/variables/upsertStyleVariable.d.ts +1 -1
  70. package/dist/src/modules/mcp/tools/preview.d.ts +3 -3
  71. package/dist/src/modules/mcp/tools/render.d.ts +3 -3
  72. package/dist/src/modules/mcp/tools/screenshot.d.ts +3 -3
  73. package/dist/src/modules/mcp/tools/shared/tool.d.ts +4 -7
  74. package/dist/src/modules/mcp/tools/validate.d.ts +3 -3
  75. package/dist/src/modules/mcp/types/appTypes.d.ts +13 -0
  76. package/dist/src/modules/mcp/types/index.d.ts +1 -0
  77. package/dist/src/plugins/validate.d.ts +9 -0
  78. package/dist/src/plugins/validate.test.d.ts +1 -0
  79. package/package.json +13 -4
  80. package/dist/modules/mcp/resources/renderApp.js +0 -182
  81. package/dist/server.d.ts +0 -1
  82. package/dist/server.js +0 -107
  83. package/dist/src/modules/mcp/resources/renderApp.d.ts +0 -3
@@ -175,8 +175,8 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
175
175
  userProvider: z.ZodOptional<z.ZodEnum<{
176
176
  "": "";
177
177
  custom: "custom";
178
- basic: "basic";
179
178
  auth0: "auth0";
179
+ basic: "basic";
180
180
  }>>;
181
181
  auth0Domain: z.ZodOptional<z.ZodString>;
182
182
  auth0ClientId: z.ZodOptional<z.ZodString>;
@@ -391,9 +391,9 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
391
391
  type: z.ZodLiteral<"upsertStyleVariable">;
392
392
  category: z.ZodEnum<{
393
393
  color: "color";
394
- custom: "custom";
395
394
  spacing: "spacing";
396
395
  shadow: "shadow";
396
+ custom: "custom";
397
397
  }>;
398
398
  name: z.ZodString;
399
399
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
@@ -405,9 +405,9 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
405
405
  type: z.ZodLiteral<"deleteStyleVariable">;
406
406
  category: z.ZodEnum<{
407
407
  color: "color";
408
- custom: "custom";
409
408
  spacing: "spacing";
410
409
  shadow: "shadow";
410
+ custom: "custom";
411
411
  }>;
412
412
  name: z.ZodString;
413
413
  }, z.core.$strip>], "type">;
@@ -590,8 +590,8 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
590
590
  userProvider: z.ZodOptional<z.ZodEnum<{
591
591
  "": "";
592
592
  custom: "custom";
593
- basic: "basic";
594
593
  auth0: "auth0";
594
+ basic: "basic";
595
595
  }>>;
596
596
  auth0Domain: z.ZodOptional<z.ZodString>;
597
597
  auth0ClientId: z.ZodOptional<z.ZodString>;
@@ -806,9 +806,9 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
806
806
  type: z.ZodLiteral<"upsertStyleVariable">;
807
807
  category: z.ZodEnum<{
808
808
  color: "color";
809
- custom: "custom";
810
809
  spacing: "spacing";
811
810
  shadow: "shadow";
811
+ custom: "custom";
812
812
  }>;
813
813
  name: z.ZodString;
814
814
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
@@ -820,9 +820,9 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
820
820
  type: z.ZodLiteral<"deleteStyleVariable">;
821
821
  category: z.ZodEnum<{
822
822
  color: "color";
823
- custom: "custom";
824
823
  spacing: "spacing";
825
824
  shadow: "shadow";
825
+ custom: "custom";
826
826
  }>;
827
827
  name: z.ZodString;
828
828
  }, z.core.$strip>], "type">>;
@@ -189,8 +189,8 @@ export declare const elementOps: {
189
189
  userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
190
190
  "": "";
191
191
  custom: "custom";
192
- basic: "basic";
193
192
  auth0: "auth0";
193
+ basic: "basic";
194
194
  }>>;
195
195
  auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
196
196
  auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
@@ -12,8 +12,8 @@ export declare const patchSettingsOp: z.ZodObject<{
12
12
  userProvider: z.ZodOptional<z.ZodEnum<{
13
13
  "": "";
14
14
  custom: "custom";
15
- basic: "basic";
16
15
  auth0: "auth0";
16
+ basic: "basic";
17
17
  }>>;
18
18
  auth0Domain: z.ZodOptional<z.ZodString>;
19
19
  auth0ClientId: z.ZodOptional<z.ZodString>;
@@ -207,9 +207,9 @@ export declare const styleOps: {
207
207
  type: import('zod').ZodLiteral<"upsertStyleVariable">;
208
208
  category: import('zod').ZodEnum<{
209
209
  color: "color";
210
- custom: "custom";
211
210
  spacing: "spacing";
212
211
  shadow: "shadow";
212
+ custom: "custom";
213
213
  }>;
214
214
  name: import('zod').ZodString;
215
215
  value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
@@ -222,9 +222,9 @@ export declare const styleOps: {
222
222
  type: import('zod').ZodLiteral<"deleteStyleVariable">;
223
223
  category: import('zod').ZodEnum<{
224
224
  color: "color";
225
- custom: "custom";
226
225
  spacing: "spacing";
227
226
  shadow: "shadow";
227
+ custom: "custom";
228
228
  }>;
229
229
  name: import('zod').ZodString;
230
230
  }, import('zod/v4/core').$strip>;
@@ -43,9 +43,9 @@ declare const definitionSlotPatch: z.ZodObject<{
43
43
  export type DefinitionSlotPatch = z.infer<typeof definitionSlotPatch>;
44
44
  export declare const styleCategory: z.ZodEnum<{
45
45
  color: "color";
46
- custom: "custom";
47
46
  spacing: "spacing";
48
47
  shadow: "shadow";
48
+ custom: "custom";
49
49
  }>;
50
50
  export declare const themeValue: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
51
51
  light: z.ZodOptional<z.ZodString>;
@@ -5,9 +5,9 @@ export declare const deleteStyleVariableOp: z.ZodObject<{
5
5
  type: z.ZodLiteral<"deleteStyleVariable">;
6
6
  category: z.ZodEnum<{
7
7
  color: "color";
8
- custom: "custom";
9
8
  spacing: "spacing";
10
9
  shadow: "shadow";
10
+ custom: "custom";
11
11
  }>;
12
12
  name: z.ZodString;
13
13
  }, z.core.$strip>;
@@ -5,9 +5,9 @@ export declare const upsertStyleVariableOp: z.ZodObject<{
5
5
  type: z.ZodLiteral<"upsertStyleVariable">;
6
6
  category: z.ZodEnum<{
7
7
  color: "color";
8
- custom: "custom";
9
8
  spacing: "spacing";
10
9
  shadow: "shadow";
10
+ custom: "custom";
11
11
  }>;
12
12
  name: z.ZodString;
13
13
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
@@ -175,8 +175,8 @@ export declare const previewShape: {
175
175
  userProvider: z.ZodOptional<z.ZodEnum<{
176
176
  "": "";
177
177
  custom: "custom";
178
- basic: "basic";
179
178
  auth0: "auth0";
179
+ basic: "basic";
180
180
  }>>;
181
181
  auth0Domain: z.ZodOptional<z.ZodString>;
182
182
  auth0ClientId: z.ZodOptional<z.ZodString>;
@@ -391,9 +391,9 @@ export declare const previewShape: {
391
391
  type: z.ZodLiteral<"upsertStyleVariable">;
392
392
  category: z.ZodEnum<{
393
393
  color: "color";
394
- custom: "custom";
395
394
  spacing: "spacing";
396
395
  shadow: "shadow";
396
+ custom: "custom";
397
397
  }>;
398
398
  name: z.ZodString;
399
399
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
@@ -405,9 +405,9 @@ export declare const previewShape: {
405
405
  type: z.ZodLiteral<"deleteStyleVariable">;
406
406
  category: z.ZodEnum<{
407
407
  color: "color";
408
- custom: "custom";
409
408
  spacing: "spacing";
410
409
  shadow: "shadow";
410
+ custom: "custom";
411
411
  }>;
412
412
  name: z.ZodString;
413
413
  }, z.core.$strip>], "type">>>;
@@ -175,8 +175,8 @@ export declare const renderShape: {
175
175
  userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
176
176
  "": "";
177
177
  custom: "custom";
178
- basic: "basic";
179
178
  auth0: "auth0";
179
+ basic: "basic";
180
180
  }>>;
181
181
  auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
182
182
  auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
@@ -391,9 +391,9 @@ export declare const renderShape: {
391
391
  type: import('zod').ZodLiteral<"upsertStyleVariable">;
392
392
  category: import('zod').ZodEnum<{
393
393
  color: "color";
394
- custom: "custom";
395
394
  spacing: "spacing";
396
395
  shadow: "shadow";
396
+ custom: "custom";
397
397
  }>;
398
398
  name: import('zod').ZodString;
399
399
  value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
@@ -405,9 +405,9 @@ export declare const renderShape: {
405
405
  type: import('zod').ZodLiteral<"deleteStyleVariable">;
406
406
  category: import('zod').ZodEnum<{
407
407
  color: "color";
408
- custom: "custom";
409
408
  spacing: "spacing";
410
409
  shadow: "shadow";
410
+ custom: "custom";
411
411
  }>;
412
412
  name: import('zod').ZodString;
413
413
  }, import('zod/v4/core').$strip>], "type">>;
@@ -175,8 +175,8 @@ export declare const screenshotShape: {
175
175
  userProvider: z.ZodOptional<z.ZodEnum<{
176
176
  "": "";
177
177
  custom: "custom";
178
- basic: "basic";
179
178
  auth0: "auth0";
179
+ basic: "basic";
180
180
  }>>;
181
181
  auth0Domain: z.ZodOptional<z.ZodString>;
182
182
  auth0ClientId: z.ZodOptional<z.ZodString>;
@@ -391,9 +391,9 @@ export declare const screenshotShape: {
391
391
  type: z.ZodLiteral<"upsertStyleVariable">;
392
392
  category: z.ZodEnum<{
393
393
  color: "color";
394
- custom: "custom";
395
394
  spacing: "spacing";
396
395
  shadow: "shadow";
396
+ custom: "custom";
397
397
  }>;
398
398
  name: z.ZodString;
399
399
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
@@ -405,9 +405,9 @@ export declare const screenshotShape: {
405
405
  type: z.ZodLiteral<"deleteStyleVariable">;
406
406
  category: z.ZodEnum<{
407
407
  color: "color";
408
- custom: "custom";
409
408
  spacing: "spacing";
410
409
  shadow: "shadow";
410
+ custom: "custom";
411
411
  }>;
412
412
  name: z.ZodString;
413
413
  }, z.core.$strip>], "type">>>;
@@ -1,6 +1,7 @@
1
1
  import { z, ZodObject, ZodRawShape } from 'zod';
2
2
  import { Space } from '../../helpers';
3
3
  import { PreviewClient, ScreenshotClient, ScreenshotImage, Env, Persisters } from '../../types';
4
+ import { McpUiToolMeta } from '@modelcontextprotocol/ext-apps';
4
5
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
5
6
  /** Everything a tool needs at call time: the loaded space, the target environment, and the persisters (only the
6
7
  * write tools use them). Built by whoever hosts the tools — the standalone MCP server or the in-process AI
@@ -35,10 +36,8 @@ export interface ToolSpec<Shape extends ZodRawShape> {
35
36
  * or load a space for it — that keeps it callable with no auth, on the public surface. */
36
37
  spaceless?: boolean;
37
38
  /** MCP Apps: link this tool to an interactive UI resource (a `ui://` HTML page the host renders in a sandboxed
38
- * iframe, receiving the tool result). The `_meta.ui` the host reads is built from this. */
39
- ui?: {
40
- resourceUri: string;
41
- };
39
+ * iframe, receiving the tool result). Registered as the tool's `_meta.ui` see registerAppTool. */
40
+ ui?: McpUiToolMeta;
42
41
  run: (input: z.infer<ZodObject<Shape>>, ctx: ToolContext) => unknown;
43
42
  }
44
43
  /** What the registry holds and the hosts register from: the same metadata plus a type-erased `execute` that
@@ -51,9 +50,7 @@ export interface ToolDef {
51
50
  access: 'read' | 'write';
52
51
  requires?: ToolRequires;
53
52
  spaceless?: boolean;
54
- ui?: {
55
- resourceUri: string;
56
- };
53
+ ui?: McpUiToolMeta;
57
54
  execute: (args: unknown, ctx: ToolContext) => unknown;
58
55
  }
59
56
  /** Author a tool: give it its metadata, its input shape and a typed `run`. The returned descriptor parses the
@@ -176,8 +176,8 @@ export declare const validateShape: {
176
176
  userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
177
177
  "": "";
178
178
  custom: "custom";
179
- basic: "basic";
180
179
  auth0: "auth0";
180
+ basic: "basic";
181
181
  }>>;
182
182
  auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
183
183
  auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
@@ -392,9 +392,9 @@ export declare const validateShape: {
392
392
  type: import('zod').ZodLiteral<"upsertStyleVariable">;
393
393
  category: import('zod').ZodEnum<{
394
394
  color: "color";
395
- custom: "custom";
396
395
  spacing: "spacing";
397
396
  shadow: "shadow";
397
+ custom: "custom";
398
398
  }>;
399
399
  name: import('zod').ZodString;
400
400
  value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
@@ -406,9 +406,9 @@ export declare const validateShape: {
406
406
  type: import('zod').ZodLiteral<"deleteStyleVariable">;
407
407
  category: import('zod').ZodEnum<{
408
408
  color: "color";
409
- custom: "custom";
410
409
  spacing: "spacing";
411
410
  shadow: "shadow";
411
+ custom: "custom";
412
412
  }>;
413
413
  name: import('zod').ZodString;
414
414
  }, import('zod/v4/core').$strip>], "type">>;
@@ -0,0 +1,13 @@
1
+ import { McpUiResourceCsp } from '@modelcontextprotocol/ext-apps';
2
+ /** A `ui://` page the host renders in a sandboxed iframe, linked from a tool through `_meta.ui.resourceUri`. */
3
+ export interface McpApp {
4
+ uri: string;
5
+ name: string;
6
+ description: string;
7
+ title: string;
8
+ /** Absolute path to the view: the app's browser entry. */
9
+ entry: string;
10
+ /** Stylesheets to inline, by absolute path — lazy so a missing one only fails on read. */
11
+ styles?: () => string[];
12
+ csp?: McpUiResourceCsp;
13
+ }
@@ -1,4 +1,5 @@
1
1
  export type * from './aiSchema';
2
+ export type * from './appTypes';
2
3
  export type * from './toolTypes';
3
4
  export type * from './previewTypes';
4
5
  export type * from './screenshotTypes';
@@ -0,0 +1,9 @@
1
+ import { PluginSource } from '@plitzi/sdk-shared';
2
+ /** The file a plugin source needs on disk, or null when nothing local is involved — a remote URL (fetched and
3
+ * cached at request time) or a component handed in directly. */
4
+ export declare const localSourcePath: (source: PluginSource) => string | null;
5
+ /** Fail at boot on a plugin whose entry file is missing. A plugin entry is a plain string path in the server
6
+ * config, so nothing — not tsc, not eslint — notices when that file is moved or deleted; without this check the
7
+ * server starts happily and only dies on the first render that needs the plugin, with an esbuild resolve error
8
+ * far from its cause. */
9
+ export declare const assertPluginSources: (plugins: Record<string, PluginSource>) => void;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plitzi/sdk-server",
3
- "version": "0.32.9",
3
+ "version": "0.32.11",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist"
@@ -13,6 +13,11 @@
13
13
  "types": "./dist/index.d.ts",
14
14
  "import": "./dist/index.js",
15
15
  "default": "./dist/index.js"
16
+ },
17
+ "./mcp": {
18
+ "types": "./dist/mcp.d.ts",
19
+ "import": "./dist/mcp.js",
20
+ "default": "./dist/mcp.js"
16
21
  }
17
22
  },
18
23
  "repository": {
@@ -22,10 +27,11 @@
22
27
  "type": "module",
23
28
  "sideEffects": false,
24
29
  "dependencies": {
30
+ "@modelcontextprotocol/ext-apps": "^1.7.5",
25
31
  "@modelcontextprotocol/sdk": "^1.29.0",
26
- "@plitzi/plitzi-sdk": "0.32.9",
27
- "@plitzi/sdk-schema": "0.32.9",
28
- "@plitzi/sdk-shared": "0.32.9",
32
+ "@plitzi/plitzi-sdk": "0.32.11",
33
+ "@plitzi/sdk-schema": "0.32.11",
34
+ "@plitzi/sdk-shared": "0.32.11",
29
35
  "ejs": "^6.0.1",
30
36
  "esbuild": "^0.28.1",
31
37
  "zod": "^4.4.3"
@@ -36,12 +42,14 @@
36
42
  },
37
43
  "devDependencies": {
38
44
  "@types/ejs": "^3.1.5",
45
+ "@types/jsdom": "^28.0.3",
39
46
  "@types/node": "^26.1.1",
40
47
  "@types/react": "^19.2.17",
41
48
  "@vitejs/plugin-react": "^6.0.4",
42
49
  "@vitest/coverage-v8": "^4.1.10",
43
50
  "eslint": "^9.39.5",
44
51
  "eslint-plugin-import": "^2.32.0",
52
+ "jsdom": "^29.1.1",
45
53
  "react": "^19.2.8",
46
54
  "react-dom": "^19.2.8",
47
55
  "tsx": "^4.23.1",
@@ -60,6 +68,7 @@
60
68
  "lint": "TIMING=1 eslint ./src",
61
69
  "typecheck": "tsc -p tsconfig.app.json --noEmit",
62
70
  "test": "vitest run",
71
+ "test:e2e": "vitest run src/modules/mcp/e2e",
63
72
  "test:coverage": "vitest run --coverage",
64
73
  "bench": "vitest bench --run"
65
74
  }
@@ -1,182 +0,0 @@
1
- //#region src/modules/mcp/resources/renderApp.ts
2
- var RENDER_APP_URI = "ui://plitzi/render.html";
3
- var RENDER_APP_MIME = "text/html;profile=mcp-app";
4
- var RENDER_APP_CSP = {
5
- resourceDomains: [
6
- "*",
7
- "data:",
8
- "blob:"
9
- ],
10
- connectDomains: ["*"]
11
- };
12
- var RENDER_APP_META = {
13
- ui: { csp: RENDER_APP_CSP },
14
- "openai/widgetCSP": {
15
- resource_domains: RENDER_APP_CSP.resourceDomains,
16
- connect_domains: RENDER_APP_CSP.connectDomains
17
- }
18
- };
19
- var appHtml = (sdkBase, devMode) => {
20
- const js = `${sdkBase}/sdk-assets/plitzi-sdk.js`;
21
- const vendor = `${sdkBase}/sdk-assets/${devMode ? "plitzi-sdk-dev-vendor.js" : "plitzi-sdk-vendor.js"}`;
22
- return `<!doctype html>
23
- <html lang="en">
24
- <head>
25
- <meta charset="utf-8" />
26
- <meta name="viewport" content="width=device-width, initial-scale=1" />
27
- <title>Plitzi widget</title>
28
- <link rel="modulepreload" href="${vendor}" crossorigin />
29
- <script type="importmap">
30
- {
31
- "imports": {
32
- "react": "${vendor}",
33
- "react-dom": "${vendor}",
34
- "react-dom/client": "${vendor}",
35
- "react/jsx-runtime": "${vendor}",
36
- "react/compiler-runtime": "${vendor}",
37
- "@plitzi/plitzi-sdk": "${js}"
38
- }
39
- }
40
- <\/script>
41
- <link href="${`${sdkBase}/sdk-assets/plitzi-sdk.css`}" rel="stylesheet" />
42
- <style>
43
- html,
44
- body {
45
- margin: 0;
46
- }
47
- #plitzi:empty::after {
48
- content: 'Rendering…';
49
- display: block;
50
- padding: 16px;
51
- font: 14px system-ui, sans-serif;
52
- color: #64748b;
53
- }
54
- </style>
55
- </head>
56
- <body>
57
- <div id="plitzi" class="plitzi-root-container"></div>
58
- <script type="module">
59
- const send = msg => window.parent.postMessage(msg, '*');
60
- const root = document.getElementById('plitzi');
61
- let mounted = false;
62
-
63
- // Replace the 'Rendering…' placeholder with an explicit failure panel — otherwise a tool that returns
64
- // { rendered:false } (no offlineData) or an SDK that fails to load would leave the iframe stuck forever.
65
- const showError = (title, details) => {
66
- mounted = true;
67
- root.textContent = '';
68
- const box = document.createElement('div');
69
- box.setAttribute('style', 'padding:16px;font:13px/1.5 system-ui,sans-serif;color:#b91c1c');
70
- const h = document.createElement('strong');
71
- h.textContent = title;
72
- box.appendChild(h);
73
- if (details) {
74
- const pre = document.createElement('pre');
75
- pre.setAttribute('style', 'margin:8px 0 0;white-space:pre-wrap;color:#7f1d1d;font-size:12px');
76
- pre.textContent = details;
77
- box.appendChild(pre);
78
- }
79
-
80
- root.appendChild(box);
81
- };
82
-
83
- // The failed-render text is the tool's JSON summary ({ rendered:false, errors:[{path,message,hint}] }).
84
- const errorText = params => {
85
- const item = Array.isArray(params && params.content) ? params.content.find(c => c.type === 'text') : undefined;
86
- if (!item) {
87
- return '';
88
- }
89
-
90
- try {
91
- const parsed = JSON.parse(item.text);
92
- if (Array.isArray(parsed.errors)) {
93
- return parsed.errors
94
- .map(e => '• ' + (e.path ? e.path + ': ' : '') + e.message + (e.hint ? ' — ' + e.hint : ''))
95
- .join('\\n');
96
- }
97
-
98
- return item.text;
99
- } catch {
100
- return item.text;
101
- }
102
- };
103
-
104
- const mount = async params => {
105
- if (mounted) {
106
- return;
107
- }
108
-
109
- const offlineData = params && params.structuredContent && params.structuredContent.offlineData;
110
- if (!offlineData) {
111
- showError('Render failed', errorText(params) || 'The tool returned no widget data.');
112
-
113
- return;
114
- }
115
-
116
- mounted = true;
117
- try {
118
- const { render } = await import('@plitzi/plitzi-sdk');
119
- render('plitzi', { offlineData, offlineMode: true, environment: 'main', renderMode: 'raw' }, {}, false, false);
120
- } catch (err) {
121
- showError('SDK failed to load', String((err && err.message) || err));
122
- }
123
- };
124
-
125
- window.addEventListener('message', event => {
126
- const msg = event.data;
127
- if (!msg || msg.jsonrpc !== '2.0') {
128
- return;
129
- }
130
-
131
- // Reply to the initialize result: the host withholds tool data until it gets our 'initialized' notification.
132
- if (msg.id === 1 && 'result' in msg) {
133
- send({ jsonrpc: '2.0', method: 'ui/notifications/initialized', params: {} });
134
-
135
- return;
136
- }
137
-
138
- if (msg.method === 'ui/notifications/tool-result') {
139
- void mount(msg.params);
140
- }
141
- });
142
-
143
- // Start the handshake immediately — nothing external blocks it, so the iframe is 'ready' at once.
144
- send({
145
- jsonrpc: '2.0',
146
- id: 1,
147
- method: 'ui/initialize',
148
- params: {
149
- protocolVersion: '2025-06-18',
150
- appInfo: { name: 'Plitzi Widget', version: '1.0.0' },
151
- appCapabilities: { availableDisplayModes: ['inline'] }
152
- }
153
- });
154
- <\/script>
155
- </body>
156
- </html>`;
157
- };
158
- var appCache = /* @__PURE__ */ new Map();
159
- var getAppHtml = (sdkBase, devMode) => {
160
- const key = `${devMode ? "dev" : "prod"}|${sdkBase}`;
161
- let html = appCache.get(key);
162
- if (!html) {
163
- html = appHtml(sdkBase, devMode);
164
- appCache.set(key, html);
165
- }
166
- return html;
167
- };
168
- var registerRenderApp = (server, sdkBase, devMode) => {
169
- const html = getAppHtml(sdkBase, devMode);
170
- server.registerResource("plitzi-render-app", RENDER_APP_URI, {
171
- description: "Interactive view that renders a plitzi_render widget with the Plitzi SDK (client-side).",
172
- mimeType: RENDER_APP_MIME,
173
- _meta: RENDER_APP_META
174
- }, () => ({ contents: [{
175
- uri: RENDER_APP_URI,
176
- mimeType: RENDER_APP_MIME,
177
- text: html,
178
- _meta: RENDER_APP_META
179
- }] }));
180
- };
181
- //#endregion
182
- export { RENDER_APP_URI, registerRenderApp };
package/dist/server.d.ts DELETED
@@ -1 +0,0 @@
1
- export {}