myoperator-mcp 0.2.59 → 0.2.61

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 +194 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1136,6 +1136,178 @@ 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";
1139
1311
  `,
1140
1312
  "delete-confirmation-modal": `import * as React from "react";
1141
1313
 
@@ -1263,7 +1435,7 @@ const DeleteConfirmationModal = React.forwardRef<
1263
1435
  <DialogContent ref={ref} size="sm" className={cn(className)}>
1264
1436
  <DialogHeader>
1265
1437
  <DialogTitle>{title || defaultTitle}</DialogTitle>
1266
- <DialogDescription className={description ? undefined : "tw-sr-only"}>
1438
+ <DialogDescription className={description ? undefined : "sr-only"}>
1267
1439
  {description ||
1268
1440
  "Delete confirmation dialog - this action cannot be undone"}
1269
1441
  </DialogDescription>
@@ -4212,6 +4384,8 @@ export const reducer = (state: State, action: Action): State => {
4212
4384
  ...state,
4213
4385
  toasts: state.toasts.filter((t) => t.id !== action.toastId),
4214
4386
  };
4387
+ default:
4388
+ return state;
4215
4389
  }
4216
4390
  };
4217
4391
 
@@ -5064,6 +5238,25 @@ var componentMetadata = {
5064
5238
  }
5065
5239
  ]
5066
5240
  },
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
+ },
5067
5260
  "delete-confirmation-modal": {
5068
5261
  "name": "DeleteConfirmationModal",
5069
5262
  "description": "A delete confirmation modal component.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.59",
3
+ "version": "0.2.61",
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",