@leanmcp/ui 0.2.0 → 0.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/dist/server.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import React__default from 'react';
2
+ export { McpUiAppResourceConfig, McpUiAppToolConfig, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, ToolConfig, registerAppResource, registerAppTool } from '@modelcontextprotocol/ext-apps/server';
2
3
 
3
4
  /**
4
5
  * @UIApp Decorator
@@ -62,4 +63,117 @@ declare function getUIAppMetadata(target: Function): UIAppOptions | undefined;
62
63
  */
63
64
  declare function getUIAppUri(target: Function): string | undefined;
64
65
 
65
- export { UIApp, type UIAppOptions, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getUIAppMetadata, getUIAppUri };
66
+ /**
67
+ * @GPTApp Decorator
68
+ *
69
+ * Links an MCP tool to a React UI component compliant with ChatGPT Apps SDK.
70
+ *
71
+ * When applied to a tool method, it:
72
+ * 1. Adds _meta.ui/resourceUri to the tool definition
73
+ * 2. Adds OpenAI-specific metadata (widgetAccessible, outputTemplate, etc.)
74
+ * 3. Auto-registers a resource that renders the component to HTML with 'text/html+skybridge' mimeType
75
+ */
76
+
77
+ declare const GPT_APP_COMPONENT_KEY = "gptapp:component";
78
+ declare const GPT_APP_URI_KEY = "gptapp:uri";
79
+ declare const GPT_APP_OPTIONS_KEY = "gptapp:options";
80
+ /**
81
+ * Options for @GPTApp decorator
82
+ */
83
+ interface GPTAppOptions {
84
+ /**
85
+ * React component or path to component file (relative to service file).
86
+ * - Use path string (e.g., './WeatherCard') for CLI build - avoids importing browser code in server
87
+ * - Use component reference for direct SSR rendering
88
+ */
89
+ component: React__default.ComponentType<any> | string;
90
+ /** Custom resource URI (auto-generated ui://... if not provided) */
91
+ uri?: string;
92
+ /** HTML document title */
93
+ title?: string;
94
+ /** Additional CSS styles */
95
+ styles?: string;
96
+ /**
97
+ * Allow widget to call tools via window.openai.callTool.
98
+ * Maps to _meta["openai/widgetAccessible"]
99
+ */
100
+ widgetAccessible?: boolean;
101
+ /**
102
+ * Tool visibility: 'public' (default) or 'private'.
103
+ * 'private' hides the tool from the model but keeps it callable by the widget.
104
+ * Maps to _meta["openai/visibility"]
105
+ */
106
+ visibility?: 'public' | 'private';
107
+ /**
108
+ * Widget prefers border around iframe.
109
+ * Maps to _meta["openai/widgetPrefersBorder"]
110
+ */
111
+ prefersBorder?: boolean;
112
+ /**
113
+ * Widget domain for API allowlists.
114
+ * Maps to _meta["openai/widgetDomain"]
115
+ */
116
+ widgetDomain?: string;
117
+ /**
118
+ * Widget description for the model.
119
+ * Maps to _meta["openai/widgetDescription"]
120
+ */
121
+ widgetDescription?: string;
122
+ /**
123
+ * Content Security Policy configuration.
124
+ * Maps to _meta["openai/widgetCSP"]
125
+ */
126
+ csp?: {
127
+ connect_domains?: string[];
128
+ resource_domains?: string[];
129
+ redirect_domains?: string[];
130
+ frame_domains?: string[];
131
+ };
132
+ /**
133
+ * File parameters (fields treated as file uploads).
134
+ * Maps to _meta["openai/fileParams"]
135
+ */
136
+ fileParams?: string[];
137
+ /**
138
+ * Invocation messages shown during tool call.
139
+ * Maps to _meta["openai/toolInvocation"]
140
+ */
141
+ invocation?: {
142
+ invoking?: string;
143
+ invoked?: string;
144
+ };
145
+ }
146
+ /**
147
+ * Decorator that links a tool to a UI component for ChatGPT Apps.
148
+ *
149
+ * When the tool is called, the host will fetch the UI resource
150
+ * which returns the component rendered as HTML with 'text/html+skybridge'.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * import { Tool } from '@leanmcp/core';
155
+ * import { GPTApp } from '@leanmcp/ui';
156
+ * import { KanbanBoard } from './KanbanBoard';
157
+ *
158
+ * class KanbanService {
159
+ * @Tool({ description: 'Show Kanban Board' })
160
+ * @GPTApp({
161
+ * component: KanbanBoard,
162
+ * widgetAccessible: true,
163
+ * invocation: { invoking: 'Loading board...' }
164
+ * })
165
+ * async showBoard() { ... }
166
+ * }
167
+ * ```
168
+ */
169
+ declare function GPTApp(options: GPTAppOptions): MethodDecorator;
170
+ /**
171
+ * Helper to get GPTApp metadata from a method
172
+ */
173
+ declare function getGPTAppMetadata(target: Function): GPTAppOptions | undefined;
174
+ /**
175
+ * Helper to get the resource URI from a method
176
+ */
177
+ declare function getGPTAppUri(target: Function): string | undefined;
178
+
179
+ export { GPTApp, type GPTAppOptions, GPT_APP_COMPONENT_KEY, GPT_APP_OPTIONS_KEY, GPT_APP_URI_KEY, UIApp, type UIAppOptions, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getGPTAppMetadata, getGPTAppUri, getUIAppMetadata, getUIAppUri };
package/dist/server.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import React__default from 'react';
2
+ export { McpUiAppResourceConfig, McpUiAppToolConfig, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, ToolConfig, registerAppResource, registerAppTool } from '@modelcontextprotocol/ext-apps/server';
2
3
 
3
4
  /**
4
5
  * @UIApp Decorator
@@ -62,4 +63,117 @@ declare function getUIAppMetadata(target: Function): UIAppOptions | undefined;
62
63
  */
63
64
  declare function getUIAppUri(target: Function): string | undefined;
64
65
 
65
- export { UIApp, type UIAppOptions, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getUIAppMetadata, getUIAppUri };
66
+ /**
67
+ * @GPTApp Decorator
68
+ *
69
+ * Links an MCP tool to a React UI component compliant with ChatGPT Apps SDK.
70
+ *
71
+ * When applied to a tool method, it:
72
+ * 1. Adds _meta.ui/resourceUri to the tool definition
73
+ * 2. Adds OpenAI-specific metadata (widgetAccessible, outputTemplate, etc.)
74
+ * 3. Auto-registers a resource that renders the component to HTML with 'text/html+skybridge' mimeType
75
+ */
76
+
77
+ declare const GPT_APP_COMPONENT_KEY = "gptapp:component";
78
+ declare const GPT_APP_URI_KEY = "gptapp:uri";
79
+ declare const GPT_APP_OPTIONS_KEY = "gptapp:options";
80
+ /**
81
+ * Options for @GPTApp decorator
82
+ */
83
+ interface GPTAppOptions {
84
+ /**
85
+ * React component or path to component file (relative to service file).
86
+ * - Use path string (e.g., './WeatherCard') for CLI build - avoids importing browser code in server
87
+ * - Use component reference for direct SSR rendering
88
+ */
89
+ component: React__default.ComponentType<any> | string;
90
+ /** Custom resource URI (auto-generated ui://... if not provided) */
91
+ uri?: string;
92
+ /** HTML document title */
93
+ title?: string;
94
+ /** Additional CSS styles */
95
+ styles?: string;
96
+ /**
97
+ * Allow widget to call tools via window.openai.callTool.
98
+ * Maps to _meta["openai/widgetAccessible"]
99
+ */
100
+ widgetAccessible?: boolean;
101
+ /**
102
+ * Tool visibility: 'public' (default) or 'private'.
103
+ * 'private' hides the tool from the model but keeps it callable by the widget.
104
+ * Maps to _meta["openai/visibility"]
105
+ */
106
+ visibility?: 'public' | 'private';
107
+ /**
108
+ * Widget prefers border around iframe.
109
+ * Maps to _meta["openai/widgetPrefersBorder"]
110
+ */
111
+ prefersBorder?: boolean;
112
+ /**
113
+ * Widget domain for API allowlists.
114
+ * Maps to _meta["openai/widgetDomain"]
115
+ */
116
+ widgetDomain?: string;
117
+ /**
118
+ * Widget description for the model.
119
+ * Maps to _meta["openai/widgetDescription"]
120
+ */
121
+ widgetDescription?: string;
122
+ /**
123
+ * Content Security Policy configuration.
124
+ * Maps to _meta["openai/widgetCSP"]
125
+ */
126
+ csp?: {
127
+ connect_domains?: string[];
128
+ resource_domains?: string[];
129
+ redirect_domains?: string[];
130
+ frame_domains?: string[];
131
+ };
132
+ /**
133
+ * File parameters (fields treated as file uploads).
134
+ * Maps to _meta["openai/fileParams"]
135
+ */
136
+ fileParams?: string[];
137
+ /**
138
+ * Invocation messages shown during tool call.
139
+ * Maps to _meta["openai/toolInvocation"]
140
+ */
141
+ invocation?: {
142
+ invoking?: string;
143
+ invoked?: string;
144
+ };
145
+ }
146
+ /**
147
+ * Decorator that links a tool to a UI component for ChatGPT Apps.
148
+ *
149
+ * When the tool is called, the host will fetch the UI resource
150
+ * which returns the component rendered as HTML with 'text/html+skybridge'.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * import { Tool } from '@leanmcp/core';
155
+ * import { GPTApp } from '@leanmcp/ui';
156
+ * import { KanbanBoard } from './KanbanBoard';
157
+ *
158
+ * class KanbanService {
159
+ * @Tool({ description: 'Show Kanban Board' })
160
+ * @GPTApp({
161
+ * component: KanbanBoard,
162
+ * widgetAccessible: true,
163
+ * invocation: { invoking: 'Loading board...' }
164
+ * })
165
+ * async showBoard() { ... }
166
+ * }
167
+ * ```
168
+ */
169
+ declare function GPTApp(options: GPTAppOptions): MethodDecorator;
170
+ /**
171
+ * Helper to get GPTApp metadata from a method
172
+ */
173
+ declare function getGPTAppMetadata(target: Function): GPTAppOptions | undefined;
174
+ /**
175
+ * Helper to get the resource URI from a method
176
+ */
177
+ declare function getGPTAppUri(target: Function): string | undefined;
178
+
179
+ export { GPTApp, type GPTAppOptions, GPT_APP_COMPONENT_KEY, GPT_APP_OPTIONS_KEY, GPT_APP_URI_KEY, UIApp, type UIAppOptions, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getGPTAppMetadata, getGPTAppUri, getUIAppMetadata, getUIAppUri };
package/dist/server.js CHANGED
@@ -1,32 +1,73 @@
1
1
  'use strict';
2
2
 
3
- var chunk3PV26V5F_js = require('./chunk-3PV26V5F.js');
3
+ var chunk2HRO6CFU_js = require('./chunk-2HRO6CFU.js');
4
+ var server = require('@modelcontextprotocol/ext-apps/server');
4
5
 
5
6
 
6
7
 
8
+ Object.defineProperty(exports, "GPTApp", {
9
+ enumerable: true,
10
+ get: function () { return chunk2HRO6CFU_js.GPTApp; }
11
+ });
12
+ Object.defineProperty(exports, "GPT_APP_COMPONENT_KEY", {
13
+ enumerable: true,
14
+ get: function () { return chunk2HRO6CFU_js.GPT_APP_COMPONENT_KEY; }
15
+ });
16
+ Object.defineProperty(exports, "GPT_APP_OPTIONS_KEY", {
17
+ enumerable: true,
18
+ get: function () { return chunk2HRO6CFU_js.GPT_APP_OPTIONS_KEY; }
19
+ });
20
+ Object.defineProperty(exports, "GPT_APP_URI_KEY", {
21
+ enumerable: true,
22
+ get: function () { return chunk2HRO6CFU_js.GPT_APP_URI_KEY; }
23
+ });
7
24
  Object.defineProperty(exports, "UIApp", {
8
25
  enumerable: true,
9
- get: function () { return chunk3PV26V5F_js.UIApp; }
26
+ get: function () { return chunk2HRO6CFU_js.UIApp; }
10
27
  });
11
28
  Object.defineProperty(exports, "UI_APP_COMPONENT_KEY", {
12
29
  enumerable: true,
13
- get: function () { return chunk3PV26V5F_js.UI_APP_COMPONENT_KEY; }
30
+ get: function () { return chunk2HRO6CFU_js.UI_APP_COMPONENT_KEY; }
14
31
  });
15
32
  Object.defineProperty(exports, "UI_APP_OPTIONS_KEY", {
16
33
  enumerable: true,
17
- get: function () { return chunk3PV26V5F_js.UI_APP_OPTIONS_KEY; }
34
+ get: function () { return chunk2HRO6CFU_js.UI_APP_OPTIONS_KEY; }
18
35
  });
19
36
  Object.defineProperty(exports, "UI_APP_URI_KEY", {
20
37
  enumerable: true,
21
- get: function () { return chunk3PV26V5F_js.UI_APP_URI_KEY; }
38
+ get: function () { return chunk2HRO6CFU_js.UI_APP_URI_KEY; }
39
+ });
40
+ Object.defineProperty(exports, "getGPTAppMetadata", {
41
+ enumerable: true,
42
+ get: function () { return chunk2HRO6CFU_js.getGPTAppMetadata; }
43
+ });
44
+ Object.defineProperty(exports, "getGPTAppUri", {
45
+ enumerable: true,
46
+ get: function () { return chunk2HRO6CFU_js.getGPTAppUri; }
22
47
  });
23
48
  Object.defineProperty(exports, "getUIAppMetadata", {
24
49
  enumerable: true,
25
- get: function () { return chunk3PV26V5F_js.getUIAppMetadata; }
50
+ get: function () { return chunk2HRO6CFU_js.getUIAppMetadata; }
26
51
  });
27
52
  Object.defineProperty(exports, "getUIAppUri", {
28
53
  enumerable: true,
29
- get: function () { return chunk3PV26V5F_js.getUIAppUri; }
54
+ get: function () { return chunk2HRO6CFU_js.getUIAppUri; }
55
+ });
56
+ Object.defineProperty(exports, "RESOURCE_MIME_TYPE", {
57
+ enumerable: true,
58
+ get: function () { return server.RESOURCE_MIME_TYPE; }
59
+ });
60
+ Object.defineProperty(exports, "RESOURCE_URI_META_KEY", {
61
+ enumerable: true,
62
+ get: function () { return server.RESOURCE_URI_META_KEY; }
63
+ });
64
+ Object.defineProperty(exports, "registerAppResource", {
65
+ enumerable: true,
66
+ get: function () { return server.registerAppResource; }
67
+ });
68
+ Object.defineProperty(exports, "registerAppTool", {
69
+ enumerable: true,
70
+ get: function () { return server.registerAppTool; }
30
71
  });
31
72
  //# sourceMappingURL=server.js.map
32
73
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"server.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"server.js","sourcesContent":[]}
package/dist/server.mjs CHANGED
@@ -1,3 +1,4 @@
1
- export { UIApp, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getUIAppMetadata, getUIAppUri } from './chunk-WORZ46KI.mjs';
1
+ export { GPTApp, GPT_APP_COMPONENT_KEY, GPT_APP_OPTIONS_KEY, GPT_APP_URI_KEY, UIApp, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, getGPTAppMetadata, getGPTAppUri, getUIAppMetadata, getUIAppUri } from './chunk-KX75VCMM.mjs';
2
+ export { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, registerAppResource, registerAppTool } from '@modelcontextprotocol/ext-apps/server';
2
3
  //# sourceMappingURL=server.mjs.map
3
4
  //# sourceMappingURL=server.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"server.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"server.mjs","sourcesContent":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanmcp/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP-Native UI SDK - React components with first-class tool integration for building MCP Apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@hookform/resolvers": "^5.2.2",
47
- "@modelcontextprotocol/ext-apps": "git+https://github.com/modelcontextprotocol/ext-apps.git",
47
+ "@modelcontextprotocol/ext-apps": "^0.2.2",
48
48
  "@modelcontextprotocol/sdk": "^1.23.0",
49
49
  "@radix-ui/react-checkbox": "^1.3.3",
50
50
  "@radix-ui/react-dialog": "^1.1.15",
@@ -1,50 +0,0 @@
1
- 'use strict';
2
-
3
- require('reflect-metadata');
4
-
5
- var __defProp = Object.defineProperty;
6
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
- var UI_APP_COMPONENT_KEY = "ui:app:component";
8
- var UI_APP_URI_KEY = "ui:app:uri";
9
- var UI_APP_OPTIONS_KEY = "ui:app:options";
10
- function UIApp(options) {
11
- return (target, propertyKey, descriptor) => {
12
- const methodName = String(propertyKey);
13
- const className = target.constructor.name.toLowerCase().replace("service", "");
14
- const uri = options.uri ?? `ui://${className}/${methodName}`;
15
- Reflect.defineMetadata(UI_APP_COMPONENT_KEY, options.component, descriptor.value);
16
- Reflect.defineMetadata(UI_APP_URI_KEY, uri, descriptor.value);
17
- Reflect.defineMetadata(UI_APP_OPTIONS_KEY, options, descriptor.value);
18
- const existingMeta = Reflect.getMetadata("tool:meta", descriptor.value) || {};
19
- Reflect.defineMetadata("tool:meta", {
20
- ...existingMeta,
21
- "ui/resourceUri": uri
22
- }, descriptor.value);
23
- return descriptor;
24
- };
25
- }
26
- __name(UIApp, "UIApp");
27
- function getUIAppMetadata(target) {
28
- const component = Reflect.getMetadata(UI_APP_COMPONENT_KEY, target);
29
- if (!component) return void 0;
30
- return {
31
- component,
32
- uri: Reflect.getMetadata(UI_APP_URI_KEY, target),
33
- ...Reflect.getMetadata(UI_APP_OPTIONS_KEY, target)
34
- };
35
- }
36
- __name(getUIAppMetadata, "getUIAppMetadata");
37
- function getUIAppUri(target) {
38
- return Reflect.getMetadata(UI_APP_URI_KEY, target);
39
- }
40
- __name(getUIAppUri, "getUIAppUri");
41
-
42
- exports.UIApp = UIApp;
43
- exports.UI_APP_COMPONENT_KEY = UI_APP_COMPONENT_KEY;
44
- exports.UI_APP_OPTIONS_KEY = UI_APP_OPTIONS_KEY;
45
- exports.UI_APP_URI_KEY = UI_APP_URI_KEY;
46
- exports.__name = __name;
47
- exports.getUIAppMetadata = getUIAppMetadata;
48
- exports.getUIAppUri = getUIAppUri;
49
- //# sourceMappingURL=chunk-3PV26V5F.js.map
50
- //# sourceMappingURL=chunk-3PV26V5F.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/decorator/UIApp.ts"],"names":["UI_APP_COMPONENT_KEY","UI_APP_URI_KEY","UI_APP_OPTIONS_KEY","UIApp","options","target","propertyKey","descriptor","methodName","String","className","name","toLowerCase","replace","uri","Reflect","defineMetadata","component","value","existingMeta","getMetadata","getUIAppMetadata","undefined","getUIAppUri"],"mappings":";;;;;;AAcO,IAAMA,oBAAAA,GAAuB;AAC7B,IAAMC,cAAAA,GAAiB;AACvB,IAAMC,kBAAAA,GAAqB;AA0C3B,SAASC,MAAMC,OAAAA,EAAqB;AACvC,EAAA,OAAO,CAACC,MAAAA,EAAgBC,WAAAA,EAA8BC,UAAAA,KAAAA;AAClD,IAAA,MAAMC,UAAAA,GAAaC,OAAOH,WAAAA,CAAAA;AAE1B,IAAA,MAAMI,SAAAA,GAAYL,OAAO,WAAA,CAAYM,IAAAA,CAAKC,aAAW,CAAGC,OAAAA,CAAQ,WAAW,EAAA,CAAA;AAG3E,IAAA,MAAMC,MAAMV,OAAAA,CAAQU,GAAAA,IAAO,CAAA,KAAA,EAAQJ,SAAAA,IAAaF,UAAAA,CAAAA,CAAAA;AAGhDO,IAAAA,OAAAA,CAAQC,cAAAA,CAAehB,oBAAAA,EAAsBI,OAAAA,CAAQa,SAAAA,EAAWV,WAAWW,KAAK,CAAA;AAChFH,IAAAA,OAAAA,CAAQC,cAAAA,CAAef,cAAAA,EAAgBa,GAAAA,EAAKP,UAAAA,CAAWW,KAAK,CAAA;AAC5DH,IAAAA,OAAAA,CAAQC,cAAAA,CAAed,kBAAAA,EAAoBE,OAAAA,EAASG,UAAAA,CAAWW,KAAK,CAAA;AAIpE,IAAA,MAAMC,eAAeJ,OAAAA,CAAQK,WAAAA,CAAY,aAAab,UAAAA,CAAWW,KAAK,KAAK,EAAC;AAC5EH,IAAAA,OAAAA,CAAQC,eAAe,WAAA,EAAa;MAChC,GAAGG,YAAAA;MACH,gBAAA,EAAkBL;AACtB,KAAA,EAAGP,WAAWW,KAAK,CAAA;AAEnB,IAAA,OAAOX,UAAAA;AACX,EAAA,CAAA;AACJ;AAxBgBJ,MAAAA,CAAAA,KAAAA,EAAAA,OAAAA,CAAAA;AA6BT,SAASkB,iBAAiBhB,MAAAA,EAAgB;AAC7C,EAAA,MAAMY,SAAAA,GAAYF,OAAAA,CAAQK,WAAAA,CAAYpB,oBAAAA,EAAsBK,MAAAA,CAAAA;AAC5D,EAAA,IAAI,CAACY,WAAW,OAAOK,MAAAA;AAEvB,EAAA,OAAO;AACHL,IAAAA,SAAAA;IACAH,GAAAA,EAAKC,OAAAA,CAAQK,WAAAA,CAAYnB,cAAAA,EAAgBI,MAAAA,CAAAA;IACzC,GAAGU,OAAAA,CAAQK,WAAAA,CAAYlB,kBAAAA,EAAoBG,MAAAA;AAC/C,GAAA;AACJ;AATgBgB,MAAAA,CAAAA,gBAAAA,EAAAA,kBAAAA,CAAAA;AAcT,SAASE,YAAYlB,MAAAA,EAAgB;AACxC,EAAA,OAAOU,OAAAA,CAAQK,WAAAA,CAAYnB,cAAAA,EAAgBI,MAAAA,CAAAA;AAC/C;AAFgBkB,MAAAA,CAAAA,WAAAA,EAAAA,aAAAA,CAAAA","file":"chunk-3PV26V5F.js","sourcesContent":["/**\r\n * @UIApp Decorator\r\n * \r\n * Links an MCP tool to a React UI component.\r\n * When applied to a tool method, it:\r\n * 1. Adds _meta.ui/resourceUri to the tool definition\r\n * 2. Auto-registers a resource that renders the component to HTML\r\n * \r\n * This decorator is designed to work with @leanmcp/core decorators.\r\n */\r\nimport 'reflect-metadata';\r\nimport type React from 'react';\r\n\r\n// Metadata keys\r\nexport const UI_APP_COMPONENT_KEY = 'ui:app:component';\r\nexport const UI_APP_URI_KEY = 'ui:app:uri';\r\nexport const UI_APP_OPTIONS_KEY = 'ui:app:options';\r\n\r\n/**\r\n * Options for @UIApp decorator\r\n */\r\nexport interface UIAppOptions {\r\n /** \r\n * React component or path to component file (relative to service file).\r\n * - Use path string (e.g., './WeatherCard') for CLI build - avoids importing browser code in server\r\n * - Use component reference for direct SSR rendering\r\n */\r\n component: React.ComponentType<any> | string;\r\n /** Custom resource URI (auto-generated if not provided) */\r\n uri?: string;\r\n /** HTML document title */\r\n title?: string;\r\n /** Additional CSS styles */\r\n styles?: string;\r\n}\r\n\r\n\r\n/**\r\n * Decorator that links a tool to a UI component.\r\n * \r\n * When the tool is called, the host will fetch the UI resource\r\n * which returns the component rendered as HTML.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Tool } from '@leanmcp/core';\r\n * import { UIApp } from '@leanmcp/ui';\r\n * import { WeatherCard } from './WeatherCard';\r\n * \r\n * class WeatherService {\r\n * @Tool({ description: 'Get weather for a city' })\r\n * @UIApp({ component: WeatherCard })\r\n * async getWeather(args: { city: string }) {\r\n * return { city: args.city, temp: 22 };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function UIApp(options: UIAppOptions): MethodDecorator {\r\n return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\r\n const methodName = String(propertyKey);\r\n // Use same pattern as @Resource in @leanmcp/core: className without 'service' suffix\r\n const className = target.constructor.name.toLowerCase().replace('service', '');\r\n\r\n // Generate URI using ui:// scheme (required by ext-apps hosts)\r\n const uri = options.uri ?? `ui://${className}/${methodName}`;\r\n\r\n // Store metadata on the method\r\n Reflect.defineMetadata(UI_APP_COMPONENT_KEY, options.component, descriptor.value!);\r\n Reflect.defineMetadata(UI_APP_URI_KEY, uri, descriptor.value!);\r\n Reflect.defineMetadata(UI_APP_OPTIONS_KEY, options, descriptor.value!);\r\n\r\n // Also store the resource URI for the @Tool decorator to pick up\r\n // The @Tool decorator in @leanmcp/core should check for this\r\n const existingMeta = Reflect.getMetadata('tool:meta', descriptor.value) || {};\r\n Reflect.defineMetadata('tool:meta', {\r\n ...existingMeta,\r\n 'ui/resourceUri': uri,\r\n }, descriptor.value!);\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Helper to get UIApp metadata from a method\r\n */\r\nexport function getUIAppMetadata(target: Function): UIAppOptions | undefined {\r\n const component = Reflect.getMetadata(UI_APP_COMPONENT_KEY, target);\r\n if (!component) return undefined;\r\n\r\n return {\r\n component,\r\n uri: Reflect.getMetadata(UI_APP_URI_KEY, target),\r\n ...Reflect.getMetadata(UI_APP_OPTIONS_KEY, target),\r\n };\r\n}\r\n\r\n/**\r\n * Helper to get the resource URI from a method\r\n */\r\nexport function getUIAppUri(target: Function): string | undefined {\r\n return Reflect.getMetadata(UI_APP_URI_KEY, target);\r\n}\r\n"]}
@@ -1,42 +0,0 @@
1
- import 'reflect-metadata';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
- var UI_APP_COMPONENT_KEY = "ui:app:component";
6
- var UI_APP_URI_KEY = "ui:app:uri";
7
- var UI_APP_OPTIONS_KEY = "ui:app:options";
8
- function UIApp(options) {
9
- return (target, propertyKey, descriptor) => {
10
- const methodName = String(propertyKey);
11
- const className = target.constructor.name.toLowerCase().replace("service", "");
12
- const uri = options.uri ?? `ui://${className}/${methodName}`;
13
- Reflect.defineMetadata(UI_APP_COMPONENT_KEY, options.component, descriptor.value);
14
- Reflect.defineMetadata(UI_APP_URI_KEY, uri, descriptor.value);
15
- Reflect.defineMetadata(UI_APP_OPTIONS_KEY, options, descriptor.value);
16
- const existingMeta = Reflect.getMetadata("tool:meta", descriptor.value) || {};
17
- Reflect.defineMetadata("tool:meta", {
18
- ...existingMeta,
19
- "ui/resourceUri": uri
20
- }, descriptor.value);
21
- return descriptor;
22
- };
23
- }
24
- __name(UIApp, "UIApp");
25
- function getUIAppMetadata(target) {
26
- const component = Reflect.getMetadata(UI_APP_COMPONENT_KEY, target);
27
- if (!component) return void 0;
28
- return {
29
- component,
30
- uri: Reflect.getMetadata(UI_APP_URI_KEY, target),
31
- ...Reflect.getMetadata(UI_APP_OPTIONS_KEY, target)
32
- };
33
- }
34
- __name(getUIAppMetadata, "getUIAppMetadata");
35
- function getUIAppUri(target) {
36
- return Reflect.getMetadata(UI_APP_URI_KEY, target);
37
- }
38
- __name(getUIAppUri, "getUIAppUri");
39
-
40
- export { UIApp, UI_APP_COMPONENT_KEY, UI_APP_OPTIONS_KEY, UI_APP_URI_KEY, __name, getUIAppMetadata, getUIAppUri };
41
- //# sourceMappingURL=chunk-WORZ46KI.mjs.map
42
- //# sourceMappingURL=chunk-WORZ46KI.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/decorator/UIApp.ts"],"names":["UI_APP_COMPONENT_KEY","UI_APP_URI_KEY","UI_APP_OPTIONS_KEY","UIApp","options","target","propertyKey","descriptor","methodName","String","className","name","toLowerCase","replace","uri","Reflect","defineMetadata","component","value","existingMeta","getMetadata","getUIAppMetadata","undefined","getUIAppUri"],"mappings":";;;;AAcO,IAAMA,oBAAAA,GAAuB;AAC7B,IAAMC,cAAAA,GAAiB;AACvB,IAAMC,kBAAAA,GAAqB;AA0C3B,SAASC,MAAMC,OAAAA,EAAqB;AACvC,EAAA,OAAO,CAACC,MAAAA,EAAgBC,WAAAA,EAA8BC,UAAAA,KAAAA;AAClD,IAAA,MAAMC,UAAAA,GAAaC,OAAOH,WAAAA,CAAAA;AAE1B,IAAA,MAAMI,SAAAA,GAAYL,OAAO,WAAA,CAAYM,IAAAA,CAAKC,aAAW,CAAGC,OAAAA,CAAQ,WAAW,EAAA,CAAA;AAG3E,IAAA,MAAMC,MAAMV,OAAAA,CAAQU,GAAAA,IAAO,CAAA,KAAA,EAAQJ,SAAAA,IAAaF,UAAAA,CAAAA,CAAAA;AAGhDO,IAAAA,OAAAA,CAAQC,cAAAA,CAAehB,oBAAAA,EAAsBI,OAAAA,CAAQa,SAAAA,EAAWV,WAAWW,KAAK,CAAA;AAChFH,IAAAA,OAAAA,CAAQC,cAAAA,CAAef,cAAAA,EAAgBa,GAAAA,EAAKP,UAAAA,CAAWW,KAAK,CAAA;AAC5DH,IAAAA,OAAAA,CAAQC,cAAAA,CAAed,kBAAAA,EAAoBE,OAAAA,EAASG,UAAAA,CAAWW,KAAK,CAAA;AAIpE,IAAA,MAAMC,eAAeJ,OAAAA,CAAQK,WAAAA,CAAY,aAAab,UAAAA,CAAWW,KAAK,KAAK,EAAC;AAC5EH,IAAAA,OAAAA,CAAQC,eAAe,WAAA,EAAa;MAChC,GAAGG,YAAAA;MACH,gBAAA,EAAkBL;AACtB,KAAA,EAAGP,WAAWW,KAAK,CAAA;AAEnB,IAAA,OAAOX,UAAAA;AACX,EAAA,CAAA;AACJ;AAxBgBJ,MAAAA,CAAAA,KAAAA,EAAAA,OAAAA,CAAAA;AA6BT,SAASkB,iBAAiBhB,MAAAA,EAAgB;AAC7C,EAAA,MAAMY,SAAAA,GAAYF,OAAAA,CAAQK,WAAAA,CAAYpB,oBAAAA,EAAsBK,MAAAA,CAAAA;AAC5D,EAAA,IAAI,CAACY,WAAW,OAAOK,MAAAA;AAEvB,EAAA,OAAO;AACHL,IAAAA,SAAAA;IACAH,GAAAA,EAAKC,OAAAA,CAAQK,WAAAA,CAAYnB,cAAAA,EAAgBI,MAAAA,CAAAA;IACzC,GAAGU,OAAAA,CAAQK,WAAAA,CAAYlB,kBAAAA,EAAoBG,MAAAA;AAC/C,GAAA;AACJ;AATgBgB,MAAAA,CAAAA,gBAAAA,EAAAA,kBAAAA,CAAAA;AAcT,SAASE,YAAYlB,MAAAA,EAAgB;AACxC,EAAA,OAAOU,OAAAA,CAAQK,WAAAA,CAAYnB,cAAAA,EAAgBI,MAAAA,CAAAA;AAC/C;AAFgBkB,MAAAA,CAAAA,WAAAA,EAAAA,aAAAA,CAAAA","file":"chunk-WORZ46KI.mjs","sourcesContent":["/**\r\n * @UIApp Decorator\r\n * \r\n * Links an MCP tool to a React UI component.\r\n * When applied to a tool method, it:\r\n * 1. Adds _meta.ui/resourceUri to the tool definition\r\n * 2. Auto-registers a resource that renders the component to HTML\r\n * \r\n * This decorator is designed to work with @leanmcp/core decorators.\r\n */\r\nimport 'reflect-metadata';\r\nimport type React from 'react';\r\n\r\n// Metadata keys\r\nexport const UI_APP_COMPONENT_KEY = 'ui:app:component';\r\nexport const UI_APP_URI_KEY = 'ui:app:uri';\r\nexport const UI_APP_OPTIONS_KEY = 'ui:app:options';\r\n\r\n/**\r\n * Options for @UIApp decorator\r\n */\r\nexport interface UIAppOptions {\r\n /** \r\n * React component or path to component file (relative to service file).\r\n * - Use path string (e.g., './WeatherCard') for CLI build - avoids importing browser code in server\r\n * - Use component reference for direct SSR rendering\r\n */\r\n component: React.ComponentType<any> | string;\r\n /** Custom resource URI (auto-generated if not provided) */\r\n uri?: string;\r\n /** HTML document title */\r\n title?: string;\r\n /** Additional CSS styles */\r\n styles?: string;\r\n}\r\n\r\n\r\n/**\r\n * Decorator that links a tool to a UI component.\r\n * \r\n * When the tool is called, the host will fetch the UI resource\r\n * which returns the component rendered as HTML.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Tool } from '@leanmcp/core';\r\n * import { UIApp } from '@leanmcp/ui';\r\n * import { WeatherCard } from './WeatherCard';\r\n * \r\n * class WeatherService {\r\n * @Tool({ description: 'Get weather for a city' })\r\n * @UIApp({ component: WeatherCard })\r\n * async getWeather(args: { city: string }) {\r\n * return { city: args.city, temp: 22 };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function UIApp(options: UIAppOptions): MethodDecorator {\r\n return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\r\n const methodName = String(propertyKey);\r\n // Use same pattern as @Resource in @leanmcp/core: className without 'service' suffix\r\n const className = target.constructor.name.toLowerCase().replace('service', '');\r\n\r\n // Generate URI using ui:// scheme (required by ext-apps hosts)\r\n const uri = options.uri ?? `ui://${className}/${methodName}`;\r\n\r\n // Store metadata on the method\r\n Reflect.defineMetadata(UI_APP_COMPONENT_KEY, options.component, descriptor.value!);\r\n Reflect.defineMetadata(UI_APP_URI_KEY, uri, descriptor.value!);\r\n Reflect.defineMetadata(UI_APP_OPTIONS_KEY, options, descriptor.value!);\r\n\r\n // Also store the resource URI for the @Tool decorator to pick up\r\n // The @Tool decorator in @leanmcp/core should check for this\r\n const existingMeta = Reflect.getMetadata('tool:meta', descriptor.value) || {};\r\n Reflect.defineMetadata('tool:meta', {\r\n ...existingMeta,\r\n 'ui/resourceUri': uri,\r\n }, descriptor.value!);\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Helper to get UIApp metadata from a method\r\n */\r\nexport function getUIAppMetadata(target: Function): UIAppOptions | undefined {\r\n const component = Reflect.getMetadata(UI_APP_COMPONENT_KEY, target);\r\n if (!component) return undefined;\r\n\r\n return {\r\n component,\r\n uri: Reflect.getMetadata(UI_APP_URI_KEY, target),\r\n ...Reflect.getMetadata(UI_APP_OPTIONS_KEY, target),\r\n };\r\n}\r\n\r\n/**\r\n * Helper to get the resource URI from a method\r\n */\r\nexport function getUIAppUri(target: Function): string | undefined {\r\n return Reflect.getMetadata(UI_APP_URI_KEY, target);\r\n}\r\n"]}