myoperator-mcp 0.2.61 → 0.2.63

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 (2) hide show
  1. package/dist/index.js +219 -193
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1136,178 +1136,6 @@ const ConfirmationModal = React.forwardRef<
1136
1136
  ConfirmationModal.displayName = "ConfirmationModal";
1137
1137
 
1138
1138
  export { ConfirmationModal };
1139
- `,
1140
- "copyable-field": `import * as React from "react";
1141
- import { Copy, Check, Eye, EyeOff } from "lucide-react";
1142
- import { cn } from "@/lib/utils";
1143
-
1144
- export interface CopyableFieldProps
1145
- extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
1146
- /** Label text displayed above the field */
1147
- label: string;
1148
- /** Value to display and copy */
1149
- value: string;
1150
- /** Helper text displayed below the field */
1151
- helperText?: string;
1152
- /** When true, masks the value with dots and shows eye toggle */
1153
- secret?: boolean;
1154
- /** Header action (e.g., "Regenerate" link) */
1155
- headerAction?: {
1156
- label: string;
1157
- onClick: () => void;
1158
- };
1159
- /** Callback when value is copied */
1160
- onValueCopy?: (value: string) => void;
1161
- /** Additional class for the input container */
1162
- inputClassName?: string;
1163
- }
1164
-
1165
- /**
1166
- * CopyableField displays a read-only value with copy-to-clipboard functionality.
1167
- * Supports secret mode for sensitive data like API keys and passwords.
1168
- *
1169
- * @example
1170
- * \`\`\`tsx
1171
- * // Simple copyable field
1172
- * <CopyableField
1173
- * label="Base URL"
1174
- * value="https://api.myoperator.co/v3/voice/gateway"
1175
- * />
1176
- *
1177
- * // Secret field with regenerate action
1178
- * <CopyableField
1179
- * label="Authentication"
1180
- * value="sk_live_abc123xyz"
1181
- * secret
1182
- * helperText="Used for client-side integrations."
1183
- * headerAction={{
1184
- * label: "Regenerate",
1185
- * onClick: () => console.log("Regenerate clicked"),
1186
- * }}
1187
- * />
1188
- * \`\`\`
1189
- */
1190
- export const CopyableField = React.forwardRef<HTMLDivElement, CopyableFieldProps>(
1191
- (
1192
- {
1193
- label,
1194
- value,
1195
- helperText,
1196
- secret = false,
1197
- headerAction,
1198
- onValueCopy,
1199
- className,
1200
- inputClassName,
1201
- ...props
1202
- },
1203
- ref
1204
- ) => {
1205
- const [copied, setCopied] = React.useState(false);
1206
- const [isVisible, setIsVisible] = React.useState(!secret);
1207
-
1208
- const handleCopy = async () => {
1209
- try {
1210
- await navigator.clipboard.writeText(value);
1211
- setCopied(true);
1212
- onValueCopy?.(value);
1213
- setTimeout(() => setCopied(false), 2000);
1214
- } catch {
1215
- // Clipboard API may fail in insecure contexts
1216
- }
1217
- };
1218
-
1219
- const toggleVisibility = () => {
1220
- setIsVisible((prev) => !prev);
1221
- };
1222
-
1223
- // Display masked or actual value
1224
- const displayValue = secret && !isVisible ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : value;
1225
-
1226
- return (
1227
- <div
1228
- ref={ref}
1229
- className={cn("flex flex-col gap-1", className)}
1230
- {...props}
1231
- >
1232
- {/* Header Row: Label + Optional Action */}
1233
- <div className="flex items-start justify-between">
1234
- <label className="text-sm text-semantic-text-muted tracking-[0.035px]">
1235
- {label}
1236
- </label>
1237
- {headerAction && (
1238
- <button
1239
- type="button"
1240
- onClick={headerAction.onClick}
1241
- className="text-sm font-semibold text-semantic-text-muted tracking-[0.014px] hover:text-semantic-text-primary transition-colors"
1242
- >
1243
- {headerAction.label}
1244
- </button>
1245
- )}
1246
- </div>
1247
-
1248
- {/* Input Container */}
1249
- <div
1250
- className={cn(
1251
- "flex h-11 items-center justify-between rounded border border-semantic-border-layout bg-semantic-bg-ui pl-4 pr-2.5 py-2.5",
1252
- inputClassName
1253
- )}
1254
- >
1255
- {/* Value Display */}
1256
- <span className="text-base text-[var(--color-primary-950)] tracking-[0.08px] truncate">
1257
- {displayValue}
1258
- </span>
1259
-
1260
- {/* Action Icons */}
1261
- <div className="flex items-center gap-4 shrink-0">
1262
- {/* Eye Toggle (only for secret mode) */}
1263
- {secret && (
1264
- <button
1265
- type="button"
1266
- onClick={toggleVisibility}
1267
- className="text-semantic-text-muted hover:text-semantic-text-primary transition-colors"
1268
- aria-label={isVisible ? "Hide value" : "Show value"}
1269
- >
1270
- {isVisible ? (
1271
- <EyeOff className="size-[18px]" />
1272
- ) : (
1273
- <Eye className="size-[18px]" />
1274
- )}
1275
- </button>
1276
- )}
1277
-
1278
- {/* Copy Button */}
1279
- <button
1280
- type="button"
1281
- onClick={handleCopy}
1282
- className={cn(
1283
- "transition-colors",
1284
- copied
1285
- ? "text-semantic-success-primary"
1286
- : "text-semantic-text-muted hover:text-semantic-text-primary"
1287
- )}
1288
- aria-label={copied ? "Copied" : "Copy to clipboard"}
1289
- >
1290
- {copied ? (
1291
- <Check className="size-[18px]" />
1292
- ) : (
1293
- <Copy className="size-[18px]" />
1294
- )}
1295
- </button>
1296
- </div>
1297
- </div>
1298
-
1299
- {/* Helper Text */}
1300
- {helperText && (
1301
- <p className="m-0 text-sm text-semantic-text-muted tracking-[0.035px]">
1302
- {helperText}
1303
- </p>
1304
- )}
1305
- </div>
1306
- );
1307
- }
1308
- );
1309
-
1310
- CopyableField.displayName = "CopyableField";
1311
1139
  `,
1312
1140
  "delete-confirmation-modal": `import * as React from "react";
1313
1141
 
@@ -2649,7 +2477,9 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
2649
2477
  // Render actions for desktop (all inline)
2650
2478
  const renderDesktopActions = () => (
2651
2479
  <div className="hidden sm:flex items-center gap-2 ml-6">
2652
- {actionsArray}
2480
+ {actionsArray.map((action, index) => (
2481
+ <React.Fragment key={index}>{action}</React.Fragment>
2482
+ ))}
2653
2483
  </div>
2654
2484
  );
2655
2485
 
@@ -2704,7 +2534,11 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
2704
2534
 
2705
2535
  // For horizontal layout, always show all actions inline
2706
2536
  const renderHorizontalActions = () => (
2707
- <div className="flex items-center gap-2 ml-4">{actionsArray}</div>
2537
+ <div className="flex items-center gap-2 ml-4">
2538
+ {actionsArray.map((action, index) => (
2539
+ <React.Fragment key={index}>{action}</React.Fragment>
2540
+ ))}
2541
+ </div>
2708
2542
  );
2709
2543
 
2710
2544
  const renderActions = () => {
@@ -2777,6 +2611,198 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
2777
2611
  PageHeader.displayName = "PageHeader";
2778
2612
 
2779
2613
  export { PageHeader, pageHeaderVariants };
2614
+ `,
2615
+ "readable-field": `import * as React from "react";
2616
+ import { Copy, Check, Eye, EyeOff } from "lucide-react";
2617
+ import { cn } from "@/lib/utils";
2618
+
2619
+ export interface ReadableFieldProps
2620
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
2621
+ /** Label text displayed above the field */
2622
+ label: string;
2623
+ /** Value to display and copy */
2624
+ value: string;
2625
+ /** Helper text displayed below the field */
2626
+ helperText?: string;
2627
+ /** When true, masks the value with dots and shows eye toggle */
2628
+ secret?: boolean;
2629
+ /** Header action (e.g., "Regenerate" link) */
2630
+ headerAction?: {
2631
+ label: string;
2632
+ onClick: () => void;
2633
+ };
2634
+ /** Callback when value is copied */
2635
+ onValueCopy?: (value: string) => void;
2636
+ /** Additional class for the input container */
2637
+ inputClassName?: string;
2638
+ }
2639
+
2640
+ /**
2641
+ * ReadableField displays a read-only value with copy-to-clipboard functionality.
2642
+ * Supports secret mode for sensitive data like API keys and passwords.
2643
+ *
2644
+ * @example
2645
+ * \`\`\`tsx
2646
+ * // Simple readable field
2647
+ * <ReadableField
2648
+ * label="Base URL"
2649
+ * value="https://api.myoperator.co/v3/voice/gateway"
2650
+ * />
2651
+ *
2652
+ * // Secret field with regenerate action
2653
+ * <ReadableField
2654
+ * label="Authentication"
2655
+ * value="sk_live_abc123xyz"
2656
+ * secret
2657
+ * helperText="Used for client-side integrations."
2658
+ * headerAction={{
2659
+ * label: "Regenerate",
2660
+ * onClick: () => console.log("Regenerate clicked"),
2661
+ * }}
2662
+ * />
2663
+ * \`\`\`
2664
+ */
2665
+ export const ReadableField = React.forwardRef<HTMLDivElement, ReadableFieldProps>(
2666
+ (
2667
+ {
2668
+ label,
2669
+ value,
2670
+ helperText,
2671
+ secret = false,
2672
+ headerAction,
2673
+ onValueCopy,
2674
+ className,
2675
+ inputClassName,
2676
+ ...props
2677
+ },
2678
+ ref
2679
+ ) => {
2680
+ const [copied, setCopied] = React.useState(false);
2681
+ const [isVisible, setIsVisible] = React.useState(!secret);
2682
+ const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
2683
+
2684
+ // Sync visibility state when secret prop changes
2685
+ React.useEffect(() => {
2686
+ setIsVisible(!secret);
2687
+ }, [secret]);
2688
+
2689
+ // Cleanup timeout on unmount to prevent memory leaks
2690
+ React.useEffect(() => {
2691
+ return () => {
2692
+ if (timeoutRef.current) {
2693
+ clearTimeout(timeoutRef.current);
2694
+ }
2695
+ };
2696
+ }, []);
2697
+
2698
+ const handleCopy = async () => {
2699
+ try {
2700
+ await navigator.clipboard.writeText(value);
2701
+ setCopied(true);
2702
+ onValueCopy?.(value);
2703
+
2704
+ // Clear existing timeout before setting new one
2705
+ if (timeoutRef.current) {
2706
+ clearTimeout(timeoutRef.current);
2707
+ }
2708
+ timeoutRef.current = setTimeout(() => setCopied(false), 2000);
2709
+ } catch {
2710
+ // Clipboard API may fail in insecure contexts
2711
+ }
2712
+ };
2713
+
2714
+ const toggleVisibility = () => {
2715
+ setIsVisible((prev) => !prev);
2716
+ };
2717
+
2718
+ // Display masked or actual value
2719
+ const displayValue = secret && !isVisible ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : value;
2720
+
2721
+ return (
2722
+ <div
2723
+ ref={ref}
2724
+ className={cn("flex flex-col gap-1", className)}
2725
+ {...props}
2726
+ >
2727
+ {/* Header Row: Label + Optional Action */}
2728
+ <div className="flex items-start justify-between">
2729
+ <span className="text-sm text-semantic-text-muted tracking-[0.035px]">
2730
+ {label}
2731
+ </span>
2732
+ {headerAction && (
2733
+ <button
2734
+ type="button"
2735
+ onClick={headerAction.onClick}
2736
+ className="text-sm font-semibold text-semantic-text-muted tracking-[0.014px] hover:text-semantic-text-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-semantic-text-primary rounded transition-colors"
2737
+ >
2738
+ {headerAction.label}
2739
+ </button>
2740
+ )}
2741
+ </div>
2742
+
2743
+ {/* Input Container */}
2744
+ <div
2745
+ className={cn(
2746
+ "flex h-11 items-center justify-between rounded border border-semantic-border-layout bg-semantic-bg-ui pl-4 pr-2.5 py-2.5",
2747
+ inputClassName
2748
+ )}
2749
+ >
2750
+ {/* Value Display */}
2751
+ <span className="text-base text-semantic-text-primary tracking-[0.08px] truncate">
2752
+ {displayValue}
2753
+ </span>
2754
+
2755
+ {/* Action Icons */}
2756
+ <div className="flex items-center gap-4 shrink-0">
2757
+ {/* Eye Toggle (only for secret mode) */}
2758
+ {secret && (
2759
+ <button
2760
+ type="button"
2761
+ onClick={toggleVisibility}
2762
+ className="text-semantic-text-muted hover:text-semantic-text-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-semantic-text-primary rounded transition-colors"
2763
+ aria-label={isVisible ? "Hide value" : "Show value"}
2764
+ >
2765
+ {isVisible ? (
2766
+ <EyeOff className="size-[18px]" />
2767
+ ) : (
2768
+ <Eye className="size-[18px]" />
2769
+ )}
2770
+ </button>
2771
+ )}
2772
+
2773
+ {/* Copy Button */}
2774
+ <button
2775
+ type="button"
2776
+ onClick={handleCopy}
2777
+ className={cn(
2778
+ "rounded transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-semantic-text-primary",
2779
+ copied
2780
+ ? "text-semantic-success-primary"
2781
+ : "text-semantic-text-muted hover:text-semantic-text-primary"
2782
+ )}
2783
+ aria-label={copied ? "Copied" : "Copy to clipboard"}
2784
+ >
2785
+ {copied ? (
2786
+ <Check className="size-[18px]" />
2787
+ ) : (
2788
+ <Copy className="size-[18px]" />
2789
+ )}
2790
+ </button>
2791
+ </div>
2792
+ </div>
2793
+
2794
+ {/* Helper Text */}
2795
+ {helperText && (
2796
+ <p className="m-0 text-sm text-semantic-text-muted tracking-[0.035px]">
2797
+ {helperText}
2798
+ </p>
2799
+ )}
2800
+ </div>
2801
+ );
2802
+ }
2803
+ );
2804
+
2805
+ ReadableField.displayName = "ReadableField";
2780
2806
  `,
2781
2807
  "select-field": `import * as React from "react";
2782
2808
  import { Loader2 } from "lucide-react";
@@ -5238,25 +5264,6 @@ var componentMetadata = {
5238
5264
  }
5239
5265
  ]
5240
5266
  },
5241
- "copyable-field": {
5242
- "name": "CopyableField",
5243
- "description": "A copyable field component.",
5244
- "dependencies": [
5245
- "class-variance-authority",
5246
- "clsx",
5247
- "tailwind-merge",
5248
- "lucide-react"
5249
- ],
5250
- "props": [],
5251
- "variants": [],
5252
- "examples": [
5253
- {
5254
- "title": "Basic CopyableField",
5255
- "code": "<CopyableField>Content</CopyableField>",
5256
- "description": "Simple copyable field usage"
5257
- }
5258
- ]
5259
- },
5260
5267
  "delete-confirmation-modal": {
5261
5268
  "name": "DeleteConfirmationModal",
5262
5269
  "description": "A delete confirmation modal component.",
@@ -5466,6 +5473,25 @@ var componentMetadata = {
5466
5473
  }
5467
5474
  ]
5468
5475
  },
5476
+ "readable-field": {
5477
+ "name": "ReadableField",
5478
+ "description": "A readable field component.",
5479
+ "dependencies": [
5480
+ "class-variance-authority",
5481
+ "clsx",
5482
+ "tailwind-merge",
5483
+ "lucide-react"
5484
+ ],
5485
+ "props": [],
5486
+ "variants": [],
5487
+ "examples": [
5488
+ {
5489
+ "title": "Basic ReadableField",
5490
+ "code": "<ReadableField>Content</ReadableField>",
5491
+ "description": "Simple readable field usage"
5492
+ }
5493
+ ]
5494
+ },
5469
5495
  "select-field": {
5470
5496
  "name": "SelectField",
5471
5497
  "description": "A form-ready select component with label, helper text, error handling, and grouped options support.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.61",
3
+ "version": "0.2.63",
4
4
  "description": "MCP server for myOperator UI components - enables AI assistants to access component metadata, examples, and design tokens",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",