myoperator-mcp 0.2.112 → 0.2.113

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 +660 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -555,7 +555,7 @@ const AlertDescription = React.forwardRef<
555
555
  HTMLParagraphElement,
556
556
  React.HTMLAttributes<HTMLParagraphElement>
557
557
  >(({ className, ...props }, ref) => (
558
- <p ref={ref} className={cn("mt-1 text-sm", className)} {...props} />
558
+ <p ref={ref} className={cn("m-0 mt-1 text-sm", className)} {...props} />
559
559
  ));
560
560
  AlertDescription.displayName = "AlertDescription";
561
561
 
@@ -1136,6 +1136,590 @@ const ConfirmationModal = React.forwardRef<
1136
1136
  ConfirmationModal.displayName = "ConfirmationModal";
1137
1137
 
1138
1138
  export { ConfirmationModal };
1139
+ `,
1140
+ "creatable-multi-select": `import * as React from "react"
1141
+ import { cva } from "class-variance-authority"
1142
+ import { ChevronDown, ChevronRight, Plus, X, Info } from "lucide-react"
1143
+
1144
+ import { cn } from "@/lib/utils"
1145
+
1146
+ const creatableMultiSelectTriggerVariants = cva(
1147
+ "flex items-center gap-2 flex-wrap min-h-[42px] w-full px-4 py-2 rounded bg-semantic-bg-primary cursor-text transition-shadow",
1148
+ {
1149
+ variants: {
1150
+ state: {
1151
+ default:
1152
+ "border border-semantic-border-input hover:border-semantic-border-input-focus",
1153
+ error:
1154
+ "border border-semantic-error-primary/40 hover:border-semantic-error-primary",
1155
+ focused:
1156
+ "border border-semantic-border-focus shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
1157
+ "focused-error":
1158
+ "border border-semantic-error-primary/60 shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
1159
+ },
1160
+ },
1161
+ defaultVariants: {
1162
+ state: "default",
1163
+ },
1164
+ }
1165
+ )
1166
+
1167
+ export interface CreatableMultiSelectOption {
1168
+ value: string
1169
+ label: string
1170
+ disabled?: boolean
1171
+ }
1172
+
1173
+ export interface CreatableMultiSelectProps
1174
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
1175
+ /** Currently selected values */
1176
+ value?: string[]
1177
+ /** Callback when values change */
1178
+ onValueChange?: (values: string[]) => void
1179
+ /** Available preset options */
1180
+ options?: CreatableMultiSelectOption[]
1181
+ /** Placeholder when no values selected */
1182
+ placeholder?: string
1183
+ /** Whether the component is disabled */
1184
+ disabled?: boolean
1185
+ /** Error state */
1186
+ state?: "default" | "error"
1187
+ /** Hint text shown at top of dropdown when open */
1188
+ creatableHint?: string
1189
+ /** Helper text shown below the trigger */
1190
+ helperText?: string
1191
+ }
1192
+
1193
+ const CreatableMultiSelect = React.forwardRef<
1194
+ HTMLDivElement,
1195
+ CreatableMultiSelectProps
1196
+ >(
1197
+ (
1198
+ {
1199
+ className,
1200
+ value = [],
1201
+ onValueChange,
1202
+ options = [],
1203
+ placeholder = "Enter or select",
1204
+ disabled = false,
1205
+ state = "default",
1206
+ creatableHint = "Type to create a custom option",
1207
+ helperText,
1208
+ ...props
1209
+ },
1210
+ ref
1211
+ ) => {
1212
+ const [isOpen, setIsOpen] = React.useState(false)
1213
+ const [inputValue, setInputValue] = React.useState("")
1214
+ const containerRef = React.useRef<HTMLDivElement>(null)
1215
+ const inputRef = React.useRef<HTMLInputElement>(null)
1216
+
1217
+ React.useImperativeHandle(ref, () => containerRef.current!)
1218
+
1219
+ const addValue = React.useCallback(
1220
+ (val: string) => {
1221
+ const trimmed = val.trim()
1222
+ if (trimmed && !value.includes(trimmed)) {
1223
+ onValueChange?.([...value, trimmed])
1224
+ setInputValue("")
1225
+ }
1226
+ },
1227
+ [value, onValueChange]
1228
+ )
1229
+
1230
+ const removeValue = React.useCallback(
1231
+ (val: string) => {
1232
+ onValueChange?.(value.filter((v) => v !== val))
1233
+ },
1234
+ [value, onValueChange]
1235
+ )
1236
+
1237
+ const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
1238
+ if (e.key === "Enter") {
1239
+ e.preventDefault()
1240
+ if (inputValue.trim()) addValue(inputValue)
1241
+ } else if (e.key === "Backspace" && !inputValue && value.length > 0) {
1242
+ removeValue(value[value.length - 1])
1243
+ } else if (e.key === "Escape") {
1244
+ setIsOpen(false)
1245
+ setInputValue("")
1246
+ }
1247
+ }
1248
+
1249
+ // Close on outside click
1250
+ React.useEffect(() => {
1251
+ const handler = (e: MouseEvent) => {
1252
+ if (
1253
+ containerRef.current &&
1254
+ !containerRef.current.contains(e.target as Node)
1255
+ ) {
1256
+ setIsOpen(false)
1257
+ setInputValue("")
1258
+ }
1259
+ }
1260
+ document.addEventListener("mousedown", handler)
1261
+ return () => document.removeEventListener("mousedown", handler)
1262
+ }, [])
1263
+
1264
+ const availablePresets = options.filter(
1265
+ (o) => !value.includes(o.value) && !o.disabled
1266
+ )
1267
+ const filteredPresets = inputValue.trim()
1268
+ ? availablePresets.filter((o) =>
1269
+ o.label.toLowerCase().includes(inputValue.trim().toLowerCase())
1270
+ )
1271
+ : availablePresets
1272
+ const canAddCustom =
1273
+ Boolean(inputValue.trim()) && !value.includes(inputValue.trim())
1274
+
1275
+ const triggerState = isOpen
1276
+ ? state === "error"
1277
+ ? "focused-error"
1278
+ : "focused"
1279
+ : state
1280
+
1281
+ return (
1282
+ <div
1283
+ ref={containerRef}
1284
+ className={cn("relative w-full", className)}
1285
+ {...props}
1286
+ >
1287
+ {/* Trigger */}
1288
+ <div
1289
+ className={cn(
1290
+ creatableMultiSelectTriggerVariants({ state: triggerState }),
1291
+ disabled && "cursor-not-allowed opacity-50"
1292
+ )}
1293
+ onClick={() => {
1294
+ if (disabled) return
1295
+ setIsOpen(true)
1296
+ inputRef.current?.focus()
1297
+ }}
1298
+ >
1299
+ {/* Selected chips */}
1300
+ {value.map((val) => {
1301
+ const optLabel =
1302
+ options.find((o) => o.value === val)?.label || val
1303
+ return (
1304
+ <span
1305
+ key={val}
1306
+ className="inline-flex items-center gap-2 bg-semantic-info-surface px-2 py-1 rounded text-sm text-semantic-text-primary whitespace-nowrap"
1307
+ >
1308
+ {optLabel}
1309
+ <button
1310
+ type="button"
1311
+ onMouseDown={(e) => {
1312
+ e.stopPropagation()
1313
+ e.preventDefault()
1314
+ removeValue(val)
1315
+ }}
1316
+ className="shrink-0 flex items-center justify-center text-semantic-text-muted hover:text-semantic-text-primary transition-colors"
1317
+ aria-label={\`Remove \${optLabel}\`}
1318
+ >
1319
+ <X className="size-2.5" />
1320
+ </button>
1321
+ </span>
1322
+ )
1323
+ })}
1324
+
1325
+ {/* Text input */}
1326
+ <input
1327
+ ref={inputRef}
1328
+ type="text"
1329
+ value={inputValue}
1330
+ onChange={(e) => {
1331
+ setInputValue(e.target.value)
1332
+ if (!isOpen) setIsOpen(true)
1333
+ }}
1334
+ onFocus={() => {
1335
+ if (!disabled) setIsOpen(true)
1336
+ }}
1337
+ onKeyDown={handleKeyDown}
1338
+ disabled={disabled}
1339
+ placeholder={value.length === 0 ? placeholder : ""}
1340
+ className="flex-1 min-w-[100px] text-base bg-transparent outline-none text-semantic-text-primary placeholder:text-semantic-text-muted"
1341
+ role="combobox"
1342
+ aria-expanded={isOpen}
1343
+ aria-haspopup="listbox"
1344
+ />
1345
+
1346
+ {/* Chevron */}
1347
+ {isOpen ? (
1348
+ <ChevronRight className="size-5 text-semantic-text-muted shrink-0 ml-auto" />
1349
+ ) : (
1350
+ <ChevronDown className="size-5 text-semantic-text-muted shrink-0 ml-auto" />
1351
+ )}
1352
+ </div>
1353
+
1354
+ {/* Dropdown panel */}
1355
+ {isOpen && (
1356
+ <div className="absolute z-[9999] top-full mt-1 w-full bg-semantic-bg-primary border border-semantic-border-layout rounded shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
1357
+ {/* Creatable hint \u2014 contextual */}
1358
+ <div className="flex items-center justify-between px-4 py-2 border-b border-semantic-border-layout">
1359
+ {canAddCustom ? (
1360
+ <span className="text-sm font-medium text-semantic-text-primary">
1361
+ Press enter to add &ldquo;{inputValue.trim()}&rdquo;
1362
+ </span>
1363
+ ) : (
1364
+ <span className="text-sm text-semantic-text-muted">
1365
+ {creatableHint}
1366
+ </span>
1367
+ )}
1368
+ <kbd className="inline-flex items-center gap-0.5 rounded border border-semantic-border-layout bg-semantic-bg-ui px-1.5 py-0.5 text-[10px] text-semantic-text-muted font-medium">
1369
+ Enter \u21B5
1370
+ </kbd>
1371
+ </div>
1372
+
1373
+ {/* Preset option chips */}
1374
+ {filteredPresets.length > 0 && (
1375
+ <div className="px-2.5 py-2 flex flex-wrap gap-1.5">
1376
+ {filteredPresets.map((option) => (
1377
+ <button
1378
+ key={option.value}
1379
+ type="button"
1380
+ onMouseDown={(e) => {
1381
+ e.preventDefault()
1382
+ addValue(option.value)
1383
+ }}
1384
+ className="inline-flex items-center gap-1.5 bg-semantic-bg-ui px-2.5 py-1.5 rounded text-sm text-semantic-text-primary hover:bg-semantic-bg-hover transition-colors whitespace-nowrap"
1385
+ >
1386
+ <Plus className="size-3 shrink-0 text-semantic-text-muted" />
1387
+ {option.label}
1388
+ </button>
1389
+ ))}
1390
+ </div>
1391
+ )}
1392
+
1393
+ </div>
1394
+ )}
1395
+
1396
+ {/* Helper text below trigger */}
1397
+ {helperText && !isOpen && (
1398
+ <div className="flex items-center gap-1.5 mt-1.5">
1399
+ <Info className="size-[18px] shrink-0 text-semantic-text-muted" />
1400
+ <p className="m-0 text-sm text-semantic-text-muted">
1401
+ {helperText}
1402
+ </p>
1403
+ </div>
1404
+ )}
1405
+ </div>
1406
+ )
1407
+ }
1408
+ )
1409
+ CreatableMultiSelect.displayName = "CreatableMultiSelect"
1410
+
1411
+ export { CreatableMultiSelect, creatableMultiSelectTriggerVariants }
1412
+ `,
1413
+ "creatable-select": `import * as React from "react"
1414
+ import { cva, type VariantProps } from "class-variance-authority"
1415
+ import { ChevronDown, Check } from "lucide-react"
1416
+
1417
+ import { cn } from "@/lib/utils"
1418
+
1419
+ const creatableSelectTriggerVariants = cva(
1420
+ "flex h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
1421
+ {
1422
+ variants: {
1423
+ state: {
1424
+ default:
1425
+ "border border-semantic-border-input focus-within:border-semantic-border-input-focus/50 focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
1426
+ error:
1427
+ "border border-semantic-error-primary/40 focus-within:border-semantic-error-primary/60 focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
1428
+ },
1429
+ },
1430
+ defaultVariants: {
1431
+ state: "default",
1432
+ },
1433
+ }
1434
+ )
1435
+
1436
+ export interface CreatableSelectOption {
1437
+ value: string
1438
+ label: string
1439
+ disabled?: boolean
1440
+ }
1441
+
1442
+ export interface CreatableSelectProps
1443
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">,
1444
+ VariantProps<typeof creatableSelectTriggerVariants> {
1445
+ /** Currently selected value */
1446
+ value?: string
1447
+ /** Callback when value changes (selection or creation) */
1448
+ onValueChange?: (value: string) => void
1449
+ /** Available options */
1450
+ options?: CreatableSelectOption[]
1451
+ /** Placeholder when no value selected */
1452
+ placeholder?: string
1453
+ /** Hint text shown above options when dropdown is open */
1454
+ creatableHint?: string
1455
+ /** Whether the select is disabled */
1456
+ disabled?: boolean
1457
+ }
1458
+
1459
+ const CreatableSelect = React.forwardRef<HTMLDivElement, CreatableSelectProps>(
1460
+ (
1461
+ {
1462
+ className,
1463
+ state,
1464
+ value,
1465
+ onValueChange,
1466
+ options = [],
1467
+ placeholder = "Select an option",
1468
+ creatableHint = "Type to create a custom option",
1469
+ disabled = false,
1470
+ ...props
1471
+ },
1472
+ ref
1473
+ ) => {
1474
+ const [open, setOpen] = React.useState(false)
1475
+ const [search, setSearch] = React.useState("")
1476
+ const [highlightIndex, setHighlightIndex] = React.useState(-1)
1477
+ const containerRef = React.useRef<HTMLDivElement>(null)
1478
+ const inputRef = React.useRef<HTMLInputElement>(null)
1479
+ const listRef = React.useRef<HTMLDivElement>(null)
1480
+
1481
+ // Merge forwarded ref with internal ref
1482
+ React.useImperativeHandle(ref, () => containerRef.current!)
1483
+
1484
+ const selectedLabel = React.useMemo(() => {
1485
+ const found = options.find((o) => o.value === value)
1486
+ return found ? found.label : value || ""
1487
+ }, [options, value])
1488
+
1489
+ const filtered = React.useMemo(() => {
1490
+ if (!search.trim()) return options
1491
+ const q = search.toLowerCase()
1492
+ return options.filter((o) => o.label.toLowerCase().includes(q))
1493
+ }, [options, search])
1494
+
1495
+ const isCustom =
1496
+ search.trim().length > 0 &&
1497
+ !options.some((o) => o.label.toLowerCase() === search.trim().toLowerCase())
1498
+
1499
+ const handleOpen = () => {
1500
+ if (disabled) return
1501
+ setOpen(true)
1502
+ setSearch("")
1503
+ setHighlightIndex(-1)
1504
+ requestAnimationFrame(() => inputRef.current?.focus())
1505
+ }
1506
+
1507
+ const handleSelect = React.useCallback(
1508
+ (val: string) => {
1509
+ onValueChange?.(val)
1510
+ setOpen(false)
1511
+ setSearch("")
1512
+ },
1513
+ [onValueChange]
1514
+ )
1515
+
1516
+ const handleCreate = React.useCallback(() => {
1517
+ const trimmed = search.trim()
1518
+ if (trimmed) {
1519
+ onValueChange?.(trimmed)
1520
+ setOpen(false)
1521
+ setSearch("")
1522
+ }
1523
+ }, [search, onValueChange])
1524
+
1525
+ const handleKeyDown = (e: React.KeyboardEvent) => {
1526
+ if (e.key === "Escape") {
1527
+ e.preventDefault()
1528
+ setOpen(false)
1529
+ return
1530
+ }
1531
+
1532
+ if (e.key === "Enter") {
1533
+ e.preventDefault()
1534
+ if (highlightIndex >= 0 && highlightIndex < filtered.length) {
1535
+ const opt = filtered[highlightIndex]
1536
+ if (!opt.disabled) handleSelect(opt.value)
1537
+ } else if (isCustom) {
1538
+ handleCreate()
1539
+ } else if (filtered.length === 1 && !filtered[0].disabled) {
1540
+ handleSelect(filtered[0].value)
1541
+ }
1542
+ return
1543
+ }
1544
+
1545
+ if (e.key === "ArrowDown") {
1546
+ e.preventDefault()
1547
+ setHighlightIndex((prev) => {
1548
+ const next = prev + 1
1549
+ return next >= filtered.length ? 0 : next
1550
+ })
1551
+ return
1552
+ }
1553
+
1554
+ if (e.key === "ArrowUp") {
1555
+ e.preventDefault()
1556
+ setHighlightIndex((prev) => {
1557
+ const next = prev - 1
1558
+ return next < 0 ? filtered.length - 1 : next
1559
+ })
1560
+ return
1561
+ }
1562
+ }
1563
+
1564
+ // Scroll highlighted item into view
1565
+ React.useEffect(() => {
1566
+ if (highlightIndex >= 0 && listRef.current) {
1567
+ const item = listRef.current.children[highlightIndex] as HTMLElement
1568
+ item?.scrollIntoView({ block: "nearest" })
1569
+ }
1570
+ }, [highlightIndex])
1571
+
1572
+ // Close on outside click
1573
+ React.useEffect(() => {
1574
+ if (!open) return
1575
+ const handler = (e: MouseEvent) => {
1576
+ if (
1577
+ containerRef.current &&
1578
+ !containerRef.current.contains(e.target as Node)
1579
+ ) {
1580
+ setOpen(false)
1581
+ }
1582
+ }
1583
+ document.addEventListener("mousedown", handler)
1584
+ return () => document.removeEventListener("mousedown", handler)
1585
+ }, [open])
1586
+
1587
+ // Reset highlight when filter changes
1588
+ React.useEffect(() => {
1589
+ setHighlightIndex(-1)
1590
+ }, [search])
1591
+
1592
+ return (
1593
+ <div
1594
+ ref={containerRef}
1595
+ className={cn("relative w-full", className)}
1596
+ {...props}
1597
+ >
1598
+ {/* Trigger / Input */}
1599
+ {open ? (
1600
+ <div
1601
+ className={cn(
1602
+ creatableSelectTriggerVariants({ state }),
1603
+ "cursor-text"
1604
+ )}
1605
+ onClick={() => inputRef.current?.focus()}
1606
+ >
1607
+ <input
1608
+ ref={inputRef}
1609
+ type="text"
1610
+ value={search}
1611
+ onChange={(e) => setSearch(e.target.value)}
1612
+ onKeyDown={handleKeyDown}
1613
+ className="flex-1 min-w-0 bg-transparent outline-none text-base text-semantic-text-primary placeholder:text-semantic-text-muted"
1614
+ placeholder={selectedLabel || placeholder}
1615
+ aria-expanded="true"
1616
+ aria-haspopup="listbox"
1617
+ role="combobox"
1618
+ aria-autocomplete="list"
1619
+ />
1620
+ <ChevronDown className="size-4 text-semantic-text-muted opacity-70 shrink-0 rotate-180 transition-transform" />
1621
+ </div>
1622
+ ) : (
1623
+ <button
1624
+ type="button"
1625
+ onClick={handleOpen}
1626
+ disabled={disabled}
1627
+ className={cn(
1628
+ creatableSelectTriggerVariants({ state }),
1629
+ "cursor-pointer text-left"
1630
+ )}
1631
+ aria-haspopup="listbox"
1632
+ aria-expanded="false"
1633
+ >
1634
+ <span
1635
+ className={cn(
1636
+ "line-clamp-1",
1637
+ !selectedLabel && "text-semantic-text-muted"
1638
+ )}
1639
+ >
1640
+ {selectedLabel || placeholder}
1641
+ </span>
1642
+ <ChevronDown className="size-4 text-semantic-text-muted opacity-70 shrink-0" />
1643
+ </button>
1644
+ )}
1645
+
1646
+ {/* Dropdown */}
1647
+ {open && (
1648
+ <div className="absolute left-0 top-full z-[9999] mt-1 w-full rounded border border-semantic-border-layout bg-semantic-bg-primary shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
1649
+ {/* Creatable hint */}
1650
+ <div className="flex items-center justify-between px-4 py-2 border-b border-semantic-border-layout">
1651
+ <span className="text-sm text-semantic-text-muted">
1652
+ {creatableHint}
1653
+ </span>
1654
+ <kbd className="inline-flex items-center gap-0.5 rounded border border-semantic-border-layout bg-semantic-bg-ui px-1.5 py-0.5 text-[10px] text-semantic-text-muted font-medium">
1655
+ Enter \u21B5
1656
+ </kbd>
1657
+ </div>
1658
+
1659
+ {/* Options list */}
1660
+ <div
1661
+ ref={listRef}
1662
+ role="listbox"
1663
+ className="max-h-60 overflow-y-auto p-1"
1664
+ >
1665
+ {filtered.length === 0 && !isCustom && (
1666
+ <div className="px-4 py-2 text-sm text-semantic-text-muted">
1667
+ No options found
1668
+ </div>
1669
+ )}
1670
+ {filtered.map((opt, i) => (
1671
+ <button
1672
+ key={opt.value}
1673
+ type="button"
1674
+ role="option"
1675
+ aria-selected={opt.value === value}
1676
+ disabled={opt.disabled}
1677
+ onClick={() => !opt.disabled && handleSelect(opt.value)}
1678
+ onMouseEnter={() => setHighlightIndex(i)}
1679
+ className={cn(
1680
+ "relative flex w-full items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none cursor-pointer select-none",
1681
+ "hover:bg-semantic-bg-ui",
1682
+ highlightIndex === i && "bg-semantic-bg-ui",
1683
+ opt.disabled &&
1684
+ "pointer-events-none opacity-50 cursor-not-allowed"
1685
+ )}
1686
+ >
1687
+ {opt.label}
1688
+ {opt.value === value && (
1689
+ <span className="absolute right-2 flex size-4 items-center justify-center">
1690
+ <Check className="size-4 text-semantic-brand" />
1691
+ </span>
1692
+ )}
1693
+ </button>
1694
+ ))}
1695
+
1696
+ {/* Show custom creation option */}
1697
+ {isCustom && (
1698
+ <button
1699
+ type="button"
1700
+ role="option"
1701
+ aria-selected={false}
1702
+ onClick={handleCreate}
1703
+ onMouseEnter={() => setHighlightIndex(filtered.length)}
1704
+ className={cn(
1705
+ "flex w-full items-center gap-2 rounded-sm py-2 pl-4 pr-8 text-base outline-none cursor-pointer select-none",
1706
+ "text-semantic-text-link hover:bg-semantic-bg-ui",
1707
+ highlightIndex === filtered.length && "bg-semantic-bg-ui"
1708
+ )}
1709
+ >
1710
+ Create &ldquo;{search.trim()}&rdquo;
1711
+ </button>
1712
+ )}
1713
+ </div>
1714
+ </div>
1715
+ )}
1716
+ </div>
1717
+ )
1718
+ }
1719
+ )
1720
+ CreatableSelect.displayName = "CreatableSelect"
1721
+
1722
+ export { CreatableSelect, creatableSelectTriggerVariants }
1139
1723
  `,
1140
1724
  "delete-confirmation-modal": `import * as React from "react";
1141
1725
 
@@ -1888,7 +2472,7 @@ import { cn } from "@/lib/utils";
1888
2472
  * Input variants for different visual states
1889
2473
  */
1890
2474
  const inputVariants = cva(
1891
- "h-10 w-full rounded bg-semantic-bg-primary px-4 py-2.5 text-sm text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
2475
+ "h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
1892
2476
  {
1893
2477
  variants: {
1894
2478
  state: {
@@ -1982,7 +2566,7 @@ import { cn } from "@/lib/utils";
1982
2566
  * MultiSelect trigger variants matching TextField styling
1983
2567
  */
1984
2568
  const multiSelectTriggerVariants = cva(
1985
- "flex min-h-10 w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-sm text-semantic-text-primary transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
2569
+ "flex min-h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
1986
2570
  {
1987
2571
  variants: {
1988
2572
  state: {
@@ -2352,7 +2936,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
2352
2936
  disabled={isDisabled}
2353
2937
  onClick={() => !isDisabled && toggleOption(option.value)}
2354
2938
  className={cn(
2355
- "relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-semantic-text-primary outline-none",
2939
+ "relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none",
2356
2940
  "hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui",
2357
2941
  isSelected && "bg-semantic-bg-ui",
2358
2942
  isDisabled && "pointer-events-none opacity-50"
@@ -2472,6 +3056,8 @@ export interface PageHeaderProps
2472
3056
  showBackButton?: boolean;
2473
3057
  /** Callback when back button is clicked */
2474
3058
  onBackClick?: () => void;
3059
+ /** Optional badge/tag displayed next to the title (e.g., status or type indicator) */
3060
+ badge?: React.ReactNode;
2475
3061
  /** Optional info icon displayed next to the title (e.g., tooltip trigger) */
2476
3062
  infoIcon?: React.ReactNode;
2477
3063
  /** Action buttons/elements rendered on the right side */
@@ -2493,6 +3079,7 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
2493
3079
  icon,
2494
3080
  showBackButton = false,
2495
3081
  onBackClick,
3082
+ badge,
2496
3083
  infoIcon,
2497
3084
  actions,
2498
3085
  showBorder = true,
@@ -2682,6 +3269,9 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
2682
3269
  <h1 className="m-0 text-lg font-semibold text-semantic-text-primary truncate">
2683
3270
  {title}
2684
3271
  </h1>
3272
+ {badge && (
3273
+ <span className="flex-shrink-0">{badge}</span>
3274
+ )}
2685
3275
  {infoIcon && (
2686
3276
  <span className="flex-shrink-0 [&_svg]:w-4 [&_svg]:h-4 text-semantic-text-muted">
2687
3277
  {infoIcon}
@@ -3559,7 +4149,7 @@ import { cn } from "@/lib/utils";
3559
4149
  * SelectTrigger variants matching TextField styling
3560
4150
  */
3561
4151
  const selectTriggerVariants = cva(
3562
- "flex h-10 w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2.5 text-sm text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)] [&>span]:line-clamp-1",
4152
+ "flex h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)] [&>span]:line-clamp-1",
3563
4153
  {
3564
4154
  variants: {
3565
4155
  state: {
@@ -3579,7 +4169,17 @@ const Select = SelectPrimitive.Root;
3579
4169
 
3580
4170
  const SelectGroup = SelectPrimitive.Group;
3581
4171
 
3582
- const SelectValue = SelectPrimitive.Value;
4172
+ const SelectValue = React.forwardRef<
4173
+ React.ElementRef<typeof SelectPrimitive.Value>,
4174
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>
4175
+ >(({ className, ...props }, ref) => (
4176
+ <SelectPrimitive.Value
4177
+ ref={ref}
4178
+ className={cn("[&[data-placeholder]]:text-semantic-text-muted", className)}
4179
+ {...props}
4180
+ />
4181
+ ));
4182
+ SelectValue.displayName = SelectPrimitive.Value.displayName;
3583
4183
 
3584
4184
  export interface SelectTriggerProps
3585
4185
  extends
@@ -3697,7 +4297,7 @@ const SelectItem = React.forwardRef<
3697
4297
  <SelectPrimitive.Item
3698
4298
  ref={ref}
3699
4299
  className={cn(
3700
- "relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-semantic-text-primary outline-none",
4300
+ "relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none",
3701
4301
  "hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui",
3702
4302
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
3703
4303
  className
@@ -4588,7 +5188,7 @@ const textFieldContainerVariants = cva(
4588
5188
  * TextField input variants (standalone without container)
4589
5189
  */
4590
5190
  const textFieldInputVariants = cva(
4591
- "h-10 w-full rounded bg-semantic-bg-primary px-4 py-2.5 text-sm text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
5191
+ "h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
4592
5192
  {
4593
5193
  variants: {
4594
5194
  state: {
@@ -4719,7 +5319,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
4719
5319
  type={type}
4720
5320
  className={cn(
4721
5321
  hasAddons
4722
- ? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-sm text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed"
5322
+ ? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-base text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed"
4723
5323
  : textFieldInputVariants({ state: derivedState, className }),
4724
5324
  type === "number" &&
4725
5325
  "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
@@ -4769,7 +5369,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
4769
5369
  state: derivedState,
4770
5370
  disabled: disabled || loading,
4771
5371
  }),
4772
- "h-10 px-4",
5372
+ "h-[42px] px-4",
4773
5373
  inputContainerClassName
4774
5374
  )}
4775
5375
  >
@@ -4866,19 +5466,19 @@ const ToastViewport = React.forwardRef<
4866
5466
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
4867
5467
 
4868
5468
  const toastVariants = cva(
4869
- "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-lg border p-4 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
5469
+ "group pointer-events-auto relative flex w-full items-center justify-between gap-4 overflow-hidden rounded-[5px] border p-3 shadow-md transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
4870
5470
  {
4871
5471
  variants: {
4872
5472
  variant: {
4873
5473
  default:
4874
5474
  "border-semantic-border-layout bg-semantic-bg-primary text-semantic-text-primary",
4875
5475
  success:
4876
- "border-semantic-success-border bg-semantic-success-surface text-semantic-success-hover",
5476
+ "border-transparent bg-semantic-success-surface text-semantic-text-primary",
4877
5477
  error:
4878
- "border-semantic-error-border bg-semantic-error-surface text-semantic-error-hover",
5478
+ "border-transparent bg-semantic-error-surface text-semantic-text-primary",
4879
5479
  warning:
4880
- "border-semantic-warning-border bg-semantic-warning-surface text-semantic-warning-hover",
4881
- info: "border-semantic-info-border bg-semantic-info-surface text-semantic-info-hover",
5480
+ "border-transparent bg-semantic-warning-surface text-semantic-text-primary",
5481
+ info: "border-transparent bg-semantic-info-surface text-semantic-text-primary",
4882
5482
  },
4883
5483
  },
4884
5484
  defaultVariants: {
@@ -4928,17 +5528,13 @@ const ToastClose = React.forwardRef<
4928
5528
  <ToastPrimitives.Close
4929
5529
  ref={ref}
4930
5530
  className={cn(
4931
- "absolute right-2 top-2 rounded-md p-1 text-semantic-text-muted opacity-0 transition-opacity hover:text-semantic-text-primary focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100",
4932
- "group-[.success]:text-semantic-success-hover group-[.success]:hover:text-semantic-success-hover",
4933
- "group-[.error]:text-semantic-error-hover group-[.error]:hover:text-semantic-error-hover",
4934
- "group-[.warning]:text-semantic-warning-hover group-[.warning]:hover:text-semantic-warning-hover",
4935
- "group-[.info]:text-semantic-info-hover group-[.info]:hover:text-semantic-info-hover",
5531
+ "shrink-0 rounded p-0.5 text-semantic-text-muted transition-colors hover:text-semantic-text-primary focus:outline-none focus:ring-2 focus:ring-semantic-border-focus",
4936
5532
  className
4937
5533
  )}
4938
5534
  toast-close=""
4939
5535
  {...props}
4940
5536
  >
4941
- <X className="h-4 w-4" />
5537
+ <X className="h-3 w-3" />
4942
5538
  </ToastPrimitives.Close>
4943
5539
  ));
4944
5540
  ToastClose.displayName = ToastPrimitives.Close.displayName;
@@ -4949,7 +5545,7 @@ const ToastTitle = React.forwardRef<
4949
5545
  >(({ className, ...props }, ref) => (
4950
5546
  <ToastPrimitives.Title
4951
5547
  ref={ref}
4952
- className={cn("text-sm font-semibold", className)}
5548
+ className={cn("text-sm font-semibold tracking-[0.014px]", className)}
4953
5549
  {...props}
4954
5550
  />
4955
5551
  ));
@@ -4961,7 +5557,7 @@ const ToastDescription = React.forwardRef<
4961
5557
  >(({ className, ...props }, ref) => (
4962
5558
  <ToastPrimitives.Description
4963
5559
  ref={ref}
4964
- className={cn("text-sm opacity-90", className)}
5560
+ className={cn("text-xs tracking-[0.048px]", className)}
4965
5561
  {...props}
4966
5562
  />
4967
5563
  ));
@@ -5240,11 +5836,11 @@ function Toaster() {
5240
5836
  className={variant ?? undefined}
5241
5837
  {...props}
5242
5838
  >
5243
- <div className="flex gap-3">
5839
+ <div className="flex items-center gap-4">
5244
5840
  {Icon && (
5245
5841
  <Icon
5246
5842
  className={cn(
5247
- "h-5 w-5 shrink-0",
5843
+ "size-6 shrink-0",
5248
5844
  variant === "success" && "text-semantic-success-primary",
5249
5845
  variant === "error" && "text-semantic-error-primary",
5250
5846
  variant === "warning" && "text-semantic-warning-primary",
@@ -5252,7 +5848,7 @@ function Toaster() {
5252
5848
  )}
5253
5849
  />
5254
5850
  )}
5255
- <div className="grid gap-1">
5851
+ <div className="flex flex-col gap-0.5">
5256
5852
  {title && <ToastTitle>{title}</ToastTitle>}
5257
5853
  {description && (
5258
5854
  <ToastDescription>{description}</ToastDescription>
@@ -5965,6 +6561,44 @@ var componentMetadata = {
5965
6561
  }
5966
6562
  ]
5967
6563
  },
6564
+ "creatable-multi-select": {
6565
+ "name": "CreatableMultiSelect",
6566
+ "description": "A creatable multi select component.",
6567
+ "dependencies": [
6568
+ "class-variance-authority",
6569
+ "clsx",
6570
+ "tailwind-merge",
6571
+ "lucide-react"
6572
+ ],
6573
+ "props": [],
6574
+ "variants": [],
6575
+ "examples": [
6576
+ {
6577
+ "title": "Basic CreatableMultiSelect",
6578
+ "code": "<CreatableMultiSelect>Content</CreatableMultiSelect>",
6579
+ "description": "Simple creatable multi select usage"
6580
+ }
6581
+ ]
6582
+ },
6583
+ "creatable-select": {
6584
+ "name": "CreatableSelect",
6585
+ "description": "A creatable select component.",
6586
+ "dependencies": [
6587
+ "class-variance-authority",
6588
+ "clsx",
6589
+ "tailwind-merge",
6590
+ "lucide-react"
6591
+ ],
6592
+ "props": [],
6593
+ "variants": [],
6594
+ "examples": [
6595
+ {
6596
+ "title": "Basic CreatableSelect",
6597
+ "code": "<CreatableSelect>Content</CreatableSelect>",
6598
+ "description": "Simple creatable select usage"
6599
+ }
6600
+ ]
6601
+ },
5968
6602
  "delete-confirmation-modal": {
5969
6603
  "name": "DeleteConfirmationModal",
5970
6604
  "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.112",
3
+ "version": "0.2.113",
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",