@kohryan/moodui 0.0.1 → 0.0.2

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/index.d.mts CHANGED
@@ -159,4 +159,32 @@ type GenerateSpecResult = {
159
159
  };
160
160
  declare function generateMoodUISpec(llm: LLMChatClient, options: GenerateSpecOptions): Promise<GenerateSpecResult>;
161
161
 
162
- export { type GeminiClientOptions, type GenerateSpecOptions, type GenerateSpecResult, type LLMChatClient, type LLMChatRequest, type LLMMessage, type MoodUIBoxNode, type MoodUIButtonNode, type MoodUIColor, type MoodUICommonProps, type MoodUIImageNode, type MoodUIInputNode, type MoodUINode, type MoodUIRadius, type MoodUISpace, type MoodUISpacerNode, type MoodUISpec, type MoodUISpecVersion, type MoodUITextNode, type MoodUITheme, type OllamaClientOptions, type OpenAICompatibleClientOptions, type RenderReactOptions, type ValidationResult, type _InternalNodeTypes, type _RenderReactExports, assertMoodUISpec, createGeminiClient, createOllamaClient, createOpenAICompatibleClient, generateMoodUISpec, renderReact, renderReactJSX, validateMoodUISpec };
162
+ type Common = {
163
+ prompt: string;
164
+ componentName?: string;
165
+ temperature?: number;
166
+ maxAttempts?: number;
167
+ };
168
+ type GenerateReactFromPromptOptions = (Common & {
169
+ provider: "gemini";
170
+ apiKey: string;
171
+ model: string;
172
+ baseUrl?: string;
173
+ }) | (Common & {
174
+ provider: "ollama";
175
+ model: string;
176
+ baseUrl?: string;
177
+ }) | (Common & {
178
+ provider: "openai-compatible";
179
+ apiKey: string;
180
+ model: string;
181
+ baseUrl: string;
182
+ });
183
+ type GenerateReactFromPromptResult = {
184
+ spec: MoodUISpec;
185
+ raw: string;
186
+ code: string;
187
+ };
188
+ declare function generateReactFromPrompt(options: GenerateReactFromPromptOptions): Promise<GenerateReactFromPromptResult>;
189
+
190
+ export { type GeminiClientOptions, type GenerateReactFromPromptOptions, type GenerateReactFromPromptResult, type GenerateSpecOptions, type GenerateSpecResult, type LLMChatClient, type LLMChatRequest, type LLMMessage, type MoodUIBoxNode, type MoodUIButtonNode, type MoodUIColor, type MoodUICommonProps, type MoodUIImageNode, type MoodUIInputNode, type MoodUINode, type MoodUIRadius, type MoodUISpace, type MoodUISpacerNode, type MoodUISpec, type MoodUISpecVersion, type MoodUITextNode, type MoodUITheme, type OllamaClientOptions, type OpenAICompatibleClientOptions, type RenderReactOptions, type ValidationResult, type _InternalNodeTypes, type _RenderReactExports, assertMoodUISpec, createGeminiClient, createOllamaClient, createOpenAICompatibleClient, generateMoodUISpec, generateReactFromPrompt, renderReact, renderReactJSX, validateMoodUISpec };
package/dist/index.d.ts CHANGED
@@ -159,4 +159,32 @@ type GenerateSpecResult = {
159
159
  };
160
160
  declare function generateMoodUISpec(llm: LLMChatClient, options: GenerateSpecOptions): Promise<GenerateSpecResult>;
161
161
 
162
- export { type GeminiClientOptions, type GenerateSpecOptions, type GenerateSpecResult, type LLMChatClient, type LLMChatRequest, type LLMMessage, type MoodUIBoxNode, type MoodUIButtonNode, type MoodUIColor, type MoodUICommonProps, type MoodUIImageNode, type MoodUIInputNode, type MoodUINode, type MoodUIRadius, type MoodUISpace, type MoodUISpacerNode, type MoodUISpec, type MoodUISpecVersion, type MoodUITextNode, type MoodUITheme, type OllamaClientOptions, type OpenAICompatibleClientOptions, type RenderReactOptions, type ValidationResult, type _InternalNodeTypes, type _RenderReactExports, assertMoodUISpec, createGeminiClient, createOllamaClient, createOpenAICompatibleClient, generateMoodUISpec, renderReact, renderReactJSX, validateMoodUISpec };
162
+ type Common = {
163
+ prompt: string;
164
+ componentName?: string;
165
+ temperature?: number;
166
+ maxAttempts?: number;
167
+ };
168
+ type GenerateReactFromPromptOptions = (Common & {
169
+ provider: "gemini";
170
+ apiKey: string;
171
+ model: string;
172
+ baseUrl?: string;
173
+ }) | (Common & {
174
+ provider: "ollama";
175
+ model: string;
176
+ baseUrl?: string;
177
+ }) | (Common & {
178
+ provider: "openai-compatible";
179
+ apiKey: string;
180
+ model: string;
181
+ baseUrl: string;
182
+ });
183
+ type GenerateReactFromPromptResult = {
184
+ spec: MoodUISpec;
185
+ raw: string;
186
+ code: string;
187
+ };
188
+ declare function generateReactFromPrompt(options: GenerateReactFromPromptOptions): Promise<GenerateReactFromPromptResult>;
189
+
190
+ export { type GeminiClientOptions, type GenerateReactFromPromptOptions, type GenerateReactFromPromptResult, type GenerateSpecOptions, type GenerateSpecResult, type LLMChatClient, type LLMChatRequest, type LLMMessage, type MoodUIBoxNode, type MoodUIButtonNode, type MoodUIColor, type MoodUICommonProps, type MoodUIImageNode, type MoodUIInputNode, type MoodUINode, type MoodUIRadius, type MoodUISpace, type MoodUISpacerNode, type MoodUISpec, type MoodUISpecVersion, type MoodUITextNode, type MoodUITheme, type OllamaClientOptions, type OpenAICompatibleClientOptions, type RenderReactOptions, type ValidationResult, type _InternalNodeTypes, type _RenderReactExports, assertMoodUISpec, createGeminiClient, createOllamaClient, createOpenAICompatibleClient, generateMoodUISpec, generateReactFromPrompt, renderReact, renderReactJSX, validateMoodUISpec };
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  createOllamaClient: () => createOllamaClient,
26
26
  createOpenAICompatibleClient: () => createOpenAICompatibleClient,
27
27
  generateMoodUISpec: () => generateMoodUISpec,
28
+ generateReactFromPrompt: () => generateReactFromPrompt,
28
29
  renderReact: () => renderReact,
29
30
  renderReactJSX: () => renderReactJSX,
30
31
  validateMoodUISpec: () => validateMoodUISpec
@@ -215,7 +216,9 @@ function buildProps(tag, node, extraProps) {
215
216
  if (props.alt) out.push(`alt=${serializeJsxAttrValue(props.alt)}`);
216
217
  if (props.fit) mergedStyle.objectFit = props.fit;
217
218
  }
218
- if (Object.keys(mergedStyle).length > 0) out.push(`style={${serializeJsValue(mergedStyle)}}`);
219
+ if (Object.keys(mergedStyle).length > 0) {
220
+ out.push(`style={(${serializeJsValue(mergedStyle)} as React.CSSProperties)}`);
221
+ }
219
222
  if (extraProps) {
220
223
  for (const [k, v] of Object.entries(extraProps)) out.push(`${k}={${v}}`);
221
224
  }
@@ -232,7 +235,7 @@ function computeStyle(tag, node) {
232
235
  applySpacing(style, "padding", props.padding);
233
236
  if (node.type === "box") {
234
237
  style.display = "flex";
235
- style.flexDirection = props.direction ?? "column";
238
+ style.flexDirection = normalizeFlexDirection(props.direction) ?? "column";
236
239
  if (props.gap != null) style.gap = normalizeCssValue(props.gap);
237
240
  if (props.align != null) style.alignItems = props.align;
238
241
  if (props.justify != null) style.justifyContent = props.justify;
@@ -314,6 +317,12 @@ function normalizeCssValue(value) {
314
317
  if (typeof value === "string") return value;
315
318
  return value;
316
319
  }
320
+ function normalizeFlexDirection(value) {
321
+ if (value === "row" || value === "column") return value;
322
+ if (value === "horizontal") return "row";
323
+ if (value === "vertical") return "column";
324
+ return void 0;
325
+ }
317
326
  function serializeJsxAttrValue(value) {
318
327
  return `{${serializeJsValue(value)}}`;
319
328
  }
@@ -568,6 +577,19 @@ function parseFirstJsonObject(text) {
568
577
  }
569
578
  throw new Error("Unterminated JSON object");
570
579
  }
580
+
581
+ // src/ai/generateReactFromPrompt.ts
582
+ async function generateReactFromPrompt(options) {
583
+ const llm = options.provider === "gemini" ? createGeminiClient({ apiKey: options.apiKey, baseUrl: options.baseUrl }) : options.provider === "ollama" ? createOllamaClient({ baseUrl: options.baseUrl }) : createOpenAICompatibleClient({ apiKey: options.apiKey, baseUrl: options.baseUrl });
584
+ const { spec, raw } = await generateMoodUISpec(llm, {
585
+ model: options.model,
586
+ prompt: options.prompt,
587
+ temperature: options.temperature,
588
+ maxAttempts: options.maxAttempts
589
+ });
590
+ const code = renderReact(spec, { componentName: options.componentName });
591
+ return { spec, raw, code };
592
+ }
571
593
  // Annotate the CommonJS export names for ESM import in node:
572
594
  0 && (module.exports = {
573
595
  assertMoodUISpec,
@@ -575,6 +597,7 @@ function parseFirstJsonObject(text) {
575
597
  createOllamaClient,
576
598
  createOpenAICompatibleClient,
577
599
  generateMoodUISpec,
600
+ generateReactFromPrompt,
578
601
  renderReact,
579
602
  renderReactJSX,
580
603
  validateMoodUISpec
package/dist/index.mjs CHANGED
@@ -182,7 +182,9 @@ function buildProps(tag, node, extraProps) {
182
182
  if (props.alt) out.push(`alt=${serializeJsxAttrValue(props.alt)}`);
183
183
  if (props.fit) mergedStyle.objectFit = props.fit;
184
184
  }
185
- if (Object.keys(mergedStyle).length > 0) out.push(`style={${serializeJsValue(mergedStyle)}}`);
185
+ if (Object.keys(mergedStyle).length > 0) {
186
+ out.push(`style={(${serializeJsValue(mergedStyle)} as React.CSSProperties)}`);
187
+ }
186
188
  if (extraProps) {
187
189
  for (const [k, v] of Object.entries(extraProps)) out.push(`${k}={${v}}`);
188
190
  }
@@ -199,7 +201,7 @@ function computeStyle(tag, node) {
199
201
  applySpacing(style, "padding", props.padding);
200
202
  if (node.type === "box") {
201
203
  style.display = "flex";
202
- style.flexDirection = props.direction ?? "column";
204
+ style.flexDirection = normalizeFlexDirection(props.direction) ?? "column";
203
205
  if (props.gap != null) style.gap = normalizeCssValue(props.gap);
204
206
  if (props.align != null) style.alignItems = props.align;
205
207
  if (props.justify != null) style.justifyContent = props.justify;
@@ -281,6 +283,12 @@ function normalizeCssValue(value) {
281
283
  if (typeof value === "string") return value;
282
284
  return value;
283
285
  }
286
+ function normalizeFlexDirection(value) {
287
+ if (value === "row" || value === "column") return value;
288
+ if (value === "horizontal") return "row";
289
+ if (value === "vertical") return "column";
290
+ return void 0;
291
+ }
284
292
  function serializeJsxAttrValue(value) {
285
293
  return `{${serializeJsValue(value)}}`;
286
294
  }
@@ -535,12 +543,26 @@ function parseFirstJsonObject(text) {
535
543
  }
536
544
  throw new Error("Unterminated JSON object");
537
545
  }
546
+
547
+ // src/ai/generateReactFromPrompt.ts
548
+ async function generateReactFromPrompt(options) {
549
+ const llm = options.provider === "gemini" ? createGeminiClient({ apiKey: options.apiKey, baseUrl: options.baseUrl }) : options.provider === "ollama" ? createOllamaClient({ baseUrl: options.baseUrl }) : createOpenAICompatibleClient({ apiKey: options.apiKey, baseUrl: options.baseUrl });
550
+ const { spec, raw } = await generateMoodUISpec(llm, {
551
+ model: options.model,
552
+ prompt: options.prompt,
553
+ temperature: options.temperature,
554
+ maxAttempts: options.maxAttempts
555
+ });
556
+ const code = renderReact(spec, { componentName: options.componentName });
557
+ return { spec, raw, code };
558
+ }
538
559
  export {
539
560
  assertMoodUISpec,
540
561
  createGeminiClient,
541
562
  createOllamaClient,
542
563
  createOpenAICompatibleClient,
543
564
  generateMoodUISpec,
565
+ generateReactFromPrompt,
544
566
  renderReact,
545
567
  renderReactJSX,
546
568
  validateMoodUISpec
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kohryan/moodui",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "MoodUI - AI-friendly UI spec + React renderer",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,