@pipelex/mthds-form 0.4.0 → 0.6.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.
Files changed (76) hide show
  1. package/README.md +15 -6
  2. package/dist/{chunk-6XD6UZSU.js → chunk-25I6JDIK.js} +2 -2
  3. package/dist/chunk-25I6JDIK.js.map +1 -0
  4. package/dist/chunk-2JWRG53S.js +33 -0
  5. package/dist/chunk-2JWRG53S.js.map +1 -0
  6. package/dist/chunk-45C2MKK6.js +94 -0
  7. package/dist/chunk-45C2MKK6.js.map +1 -0
  8. package/dist/chunk-4BSBBG2T.js +80 -0
  9. package/dist/chunk-4BSBBG2T.js.map +1 -0
  10. package/dist/{chunk-7BMOPXDY.js → chunk-GCXV76WU.js} +17 -9
  11. package/dist/chunk-GCXV76WU.js.map +1 -0
  12. package/dist/chunk-IIU3YK4O.js +16 -0
  13. package/dist/chunk-IIU3YK4O.js.map +1 -0
  14. package/dist/chunk-J4L32LD6.js +137 -0
  15. package/dist/chunk-J4L32LD6.js.map +1 -0
  16. package/dist/{chunk-KFZ5MZOM.js → chunk-LBFZXYCY.js} +3 -3
  17. package/dist/{chunk-KFZ5MZOM.js.map → chunk-LBFZXYCY.js.map} +1 -1
  18. package/dist/{chunk-O4O3QNVC.js → chunk-OD3VYXUY.js} +13 -3
  19. package/dist/chunk-OD3VYXUY.js.map +1 -0
  20. package/dist/{chunk-XEPD5VJQ.js → chunk-R7B7ID25.js} +8 -8
  21. package/dist/chunk-R7B7ID25.js.map +1 -0
  22. package/dist/{chunk-WXBSM2CE.js → chunk-T4NSAGOS.js} +8 -8
  23. package/dist/chunk-T4NSAGOS.js.map +1 -0
  24. package/dist/{chunk-HARYEWNG.js → chunk-XYQ7NXQZ.js} +2 -2
  25. package/dist/chunk-XYQ7NXQZ.js.map +1 -0
  26. package/dist/chunk-YEVVR6FE.js +66 -0
  27. package/dist/chunk-YEVVR6FE.js.map +1 -0
  28. package/dist/core/contracts.d.ts +27 -56
  29. package/dist/core/contracts.js +1 -1
  30. package/dist/core/derive.d.ts +79 -11
  31. package/dist/core/derive.js +4 -4
  32. package/dist/core/descriptor.d.ts +70 -26
  33. package/dist/core/descriptor.js +1 -1
  34. package/dist/core/file-formats.d.ts +102 -0
  35. package/dist/core/file-formats.js +3 -0
  36. package/dist/core/file-formats.js.map +1 -0
  37. package/dist/core/gate.d.ts +1 -1
  38. package/dist/core/gate.js +7 -8
  39. package/dist/core/gating-fields.d.ts +38 -0
  40. package/dist/core/gating-fields.js +6 -0
  41. package/dist/core/gating-fields.js.map +1 -0
  42. package/dist/core/index.d.ts +8 -3
  43. package/dist/core/index.js +14 -10
  44. package/dist/core/native-content.d.ts +219 -0
  45. package/dist/core/native-content.js +4 -0
  46. package/dist/core/{native-concepts.js.map → native-content.js.map} +1 -1
  47. package/dist/core/normalize-schema.js +2 -2
  48. package/dist/core/output-form.d.ts +45 -0
  49. package/dist/core/output-form.js +5 -0
  50. package/dist/core/output-form.js.map +1 -0
  51. package/dist/core/readiness.d.ts +2 -0
  52. package/dist/core/schema-utils.d.ts +13 -1
  53. package/dist/core/schema-utils.js +1 -1
  54. package/dist/core/stuff-files.d.ts +52 -0
  55. package/dist/core/stuff-files.js +5 -0
  56. package/dist/core/stuff-files.js.map +1 -0
  57. package/dist/core/values.d.ts +10 -3
  58. package/dist/core/values.js +7 -7
  59. package/dist/core/wire-format.js +3 -4
  60. package/dist/react/index.d.ts +278 -1
  61. package/dist/react/index.js +1378 -29
  62. package/dist/react/index.js.map +1 -1
  63. package/dist/styles.css +1 -1
  64. package/package.json +17 -3
  65. package/dist/chunk-6XD6UZSU.js.map +0 -1
  66. package/dist/chunk-7BMOPXDY.js.map +0 -1
  67. package/dist/chunk-HARYEWNG.js.map +0 -1
  68. package/dist/chunk-NMT7BRLO.js +0 -40
  69. package/dist/chunk-NMT7BRLO.js.map +0 -1
  70. package/dist/chunk-O4O3QNVC.js.map +0 -1
  71. package/dist/chunk-VMLXO5JS.js +0 -132
  72. package/dist/chunk-VMLXO5JS.js.map +0 -1
  73. package/dist/chunk-WXBSM2CE.js.map +0 -1
  74. package/dist/chunk-XEPD5VJQ.js.map +0 -1
  75. package/dist/core/native-concepts.d.ts +0 -78
  76. package/dist/core/native-concepts.js +0 -3
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
2
- /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.left-2{left:.5rem}.z-50{z-index:50}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.size-3\.5{width:.875rem;height:.875rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[78vh\]{height:78vh}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-px{height:1px}.max-h-\[--radix-select-content-available-height\]{max-height:var(--radix-select-content-available-height)}.max-h-\[640px\]{max-height:640px}.min-h-\[520px\]{min-height:520px}.min-h-\[80px\]{min-height:80px}.min-h-\[88px\]{min-height:88px}.w-11{width:2.75rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-10{min-width:2.5rem}.min-w-11{min-width:2.75rem}.min-w-9{min-width:2.25rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-full{max-width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.origin-\[--radix-select-content-transform-origin\]{transform-origin:var(--radix-select-content-transform-origin)}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-y{resize:vertical}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-y-1{row-gap:.25rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-width:1px}.border-2{border-width:2px}.border-dashed{border-style:dashed}.border-border{border-color:hsl(var(--border))}.border-destructive\/50{border-color:hsl(var(--destructive)/.5)}.border-input{border-color:hsl(var(--input))}.border-primary\/60{border-color:hsl(var(--primary)/.6)}.border-transparent{border-color:transparent}.bg-background{background-color:hsl(var(--background))}.bg-card\/40{background-color:hsl(var(--card)/.4)}.bg-input{background-color:hsl(var(--input))}.bg-input\/50{background-color:hsl(var(--input)/.5)}.bg-muted{background-color:hsl(var(--muted))}.bg-popover{background-color:hsl(var(--popover))}.bg-primary\/5{background-color:hsl(var(--primary)/.05)}.bg-transparent{background-color:transparent}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pl-8{padding-left:2rem}.pr-2{padding-right:.5rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-wider{letter-spacing:.05em}.text-destructive{color:hsl(var(--destructive))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/70{color:hsl(var(--muted-foreground)/.7)}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring,.ring-0{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-destructive\/70{--tw-ring-color:hsl(var(--destructive)/0.7)}.ring-offset-4{--tw-ring-offset-width:4px}.ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.\[appearance\:textfield\]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.\[field-sizing\:content\]{field-sizing:content}.placeholder\:text-muted-foreground\/70::-moz-placeholder{color:hsl(var(--muted-foreground)/.7)}.placeholder\:text-muted-foreground\/70::placeholder{color:hsl(var(--muted-foreground)/.7)}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-within\:ring-ring:focus-within{--tw-ring-color:hsl(var(--ring))}.focus-within\:ring-offset-2:focus-within{--tw-ring-offset-width:2px}.focus-within\:ring-offset-background:focus-within{--tw-ring-offset-color:hsl(var(--background))}.hover\:border-border:hover{border-color:hsl(var(--border))}.hover\:border-primary\/40:hover{border-color:hsl(var(--primary)/.4)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-muted-foreground:hover{color:hsl(var(--muted-foreground))}.focus\:border-ring:focus{border-color:hsl(var(--ring))}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\:border-primary:focus-visible{border-color:hsl(var(--primary))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:hsl(var(--primary)/0.4)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:hsl(var(--background))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.aria-\[invalid\=true\]\:border-destructive[aria-invalid=true]{border-color:hsl(var(--destructive))}.aria-\[invalid\=true\]\:ring-destructive\/30[aria-invalid=true]{--tw-ring-color:hsl(var(--destructive)/0.3)}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:0.25rem}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom],.data-\[side\=left\]\:-translate-x-1[data-side=left]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:-0.25rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:0.25rem}.data-\[side\=right\]\:translate-x-1[data-side=right],.data-\[side\=top\]\:-translate-y-1[data-side=top]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:-0.25rem}.data-\[state\=checked\]\:translate-x-5[data-state=checked]{--tw-translate-x:1.25rem}.data-\[state\=checked\]\:translate-x-5[data-state=checked],.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x:0px}.data-\[state\=on\]\:border-primary\/40[data-state=on]{border-color:hsl(var(--primary)/.4)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=on\]\:bg-accent[data-state=on]{background-color:hsl(var(--accent))}.data-\[state\=on\]\:bg-primary\/10[data-state=on]{background-color:hsl(var(--primary)/.1)}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[state\=on\]\:font-medium[data-state=on]{font-weight:500}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:hsl(var(--muted-foreground))}.data-\[state\=on\]\:text-accent-foreground[data-state=on]{color:hsl(var(--accent-foreground))}.data-\[state\=on\]\:text-foreground[data-state=on]{color:hsl(var(--foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=open\]\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-0.5rem}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:0.5rem}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-0.5rem}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:0.5rem}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}
2
+ /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.left-0{left:0}.left-2{left:.5rem}.right-2{right:.5rem}.top-2{top:.5rem}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.me-1\.5{margin-inline-end:.375rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.size-3\.5{width:.875rem;height:.875rem}.size-4{width:1rem;height:1rem}.size-5{width:1.25rem;height:1.25rem}.size-6{width:1.5rem;height:1.5rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[28rem\]{height:28rem}.h-\[78vh\]{height:78vh}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-px{height:1px}.max-h-64{max-height:16rem}.max-h-\[--radix-select-content-available-height\]{max-height:var(--radix-select-content-available-height)}.max-h-\[44rem\]{max-height:44rem}.max-h-\[640px\]{max-height:640px}.min-h-40{min-height:10rem}.min-h-\[520px\]{min-height:520px}.min-h-\[80px\]{min-height:80px}.min-h-\[88px\]{min-height:88px}.w-11{width:2.75rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-auto{width:auto}.w-full{width:100%}.min-w-0{min-width:0}.min-w-10{min-width:2.5rem}.min-w-11{min-width:2.75rem}.min-w-9{min-width:2.25rem}.min-w-\[16ch\]{min-width:16ch}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-full{min-width:100%}.max-w-\[44ch\]{max-width:44ch}.max-w-full{max-width:100%}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.origin-\[--radix-select-content-transform-origin\]{transform-origin:var(--radix-select-content-transform-origin)}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-y{resize:vertical}.resize{resize:both}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-\[minmax\(min-content\2c 40\%\)_minmax\(0\2c 1fr\)\]{grid-template-columns:minmax(min-content,40%) minmax(0,1fr)}.grid-cols-\[repeat\(auto-fill\2c minmax\(140px\2c 1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-1{row-gap:.25rem}.gap-y-1\.5{row-gap:.375rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-border>:not([hidden])~:not([hidden]){border-color:hsl(var(--border))}.divide-border\/60>:not([hidden])~:not([hidden]){border-color:hsl(var(--border)/.6)}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-s-2{border-inline-start-width:2px}.border-dashed{border-style:dashed}.border-border{border-color:hsl(var(--border))}.border-border\/60{border-color:hsl(var(--border)/.6)}.border-destructive\/50{border-color:hsl(var(--destructive)/.5)}.border-input{border-color:hsl(var(--input))}.border-primary\/60{border-color:hsl(var(--primary)/.6)}.border-transparent{border-color:transparent}.bg-background{background-color:hsl(var(--background))}.bg-card{background-color:hsl(var(--card))}.bg-card\/40{background-color:hsl(var(--card)/.4)}.bg-input{background-color:hsl(var(--input))}.bg-input\/50{background-color:hsl(var(--input)/.5)}.bg-muted{background-color:hsl(var(--muted))}.bg-popover{background-color:hsl(var(--popover))}.bg-primary\/5{background-color:hsl(var(--primary)/.05)}.bg-transparent{background-color:transparent}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-1\.5{padding-bottom:.375rem}.pl-8{padding-left:2rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.ps-3{padding-inline-start:.75rem}.ps-5{padding-inline-start:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-start{text-align:start}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[0\.92em\]{font-size:.92em}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[14\.5px\]{font-size:14.5px}.text-\[16px\]{font-size:16px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-wider{letter-spacing:.05em}.text-destructive{color:hsl(var(--destructive))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring,.ring-0{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-destructive\/70{--tw-ring-color:hsl(var(--destructive)/0.7)}.ring-offset-4{--tw-ring-offset-width:4px}.ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.animate-in{animation-name:enter;animation-duration:.15s;--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial}.fade-in-0{--tw-enter-opacity:0}.zoom-in-95{--tw-enter-scale:.95}.running{animation-play-state:running}.\[appearance\:textfield\]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.\[field-sizing\:content\]{field-sizing:content}.marker\:text-muted-foreground ::marker{color:hsl(var(--muted-foreground))}.marker\:text-muted-foreground::marker{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground\/70::-moz-placeholder{color:hsl(var(--muted-foreground)/.7)}.placeholder\:text-muted-foreground\/70::placeholder{color:hsl(var(--muted-foreground)/.7)}.first\:mt-0:first-child{margin-top:0}.last\:border-b-0:last-child{border-bottom-width:0}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-within\:ring-ring:focus-within{--tw-ring-color:hsl(var(--ring))}.focus-within\:ring-offset-2:focus-within{--tw-ring-offset-width:2px}.focus-within\:ring-offset-background:focus-within{--tw-ring-offset-color:hsl(var(--background))}.hover\:border-border:hover{border-color:hsl(var(--border))}.hover\:border-primary\/40:hover{border-color:hsl(var(--primary)/.4)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-card:hover{background-color:hsl(var(--card))}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-muted-foreground:hover{color:hsl(var(--muted-foreground))}.focus\:border-ring:focus{border-color:hsl(var(--ring))}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\:border-primary:focus-visible{border-color:hsl(var(--primary))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:outline:focus-visible{outline-style:solid}.focus-visible\:outline-2:focus-visible{outline-width:2px}.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:hsl(var(--primary)/0.4)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:hsl(var(--background))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.aria-\[invalid\=true\]\:border-destructive[aria-invalid=true]{border-color:hsl(var(--destructive))}.aria-\[invalid\=true\]\:ring-destructive\/30[aria-invalid=true]{--tw-ring-color:hsl(var(--destructive)/0.3)}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:0.25rem}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom],.data-\[side\=left\]\:-translate-x-1[data-side=left]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:-0.25rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:0.25rem}.data-\[side\=right\]\:translate-x-1[data-side=right],.data-\[side\=top\]\:-translate-y-1[data-side=top]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:-0.25rem}.data-\[state\=checked\]\:translate-x-5[data-state=checked]{--tw-translate-x:1.25rem}.data-\[state\=checked\]\:translate-x-5[data-state=checked],.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x:0px}.data-\[state\=on\]\:border-primary\/40[data-state=on]{border-color:hsl(var(--primary)/.4)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=on\]\:bg-accent[data-state=on]{background-color:hsl(var(--accent))}.data-\[state\=on\]\:bg-primary\/10[data-state=on]{background-color:hsl(var(--primary)/.1)}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:hsl(var(--input))}.data-\[state\=on\]\:font-medium[data-state=on]{font-weight:500}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:hsl(var(--muted-foreground))}.data-\[state\=on\]\:text-accent-foreground[data-state=on]{color:hsl(var(--accent-foreground))}.data-\[state\=on\]\:text-foreground[data-state=on]{color:hsl(var(--foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=open\]\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-0.5rem}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:0.5rem}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-0.5rem}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:0.5rem}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipelex/mthds-form",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Headless form kernel and control set for MTHDS method inputs",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,9 +39,11 @@
39
39
  "build": "tsup && npm run build:css",
40
40
  "build:css": "tailwindcss -c tailwind.config.cjs -i src/styles/tailwind-entry.css -o dist/styles.css --minify && cp src/styles/theme.css dist/theme.css",
41
41
  "lint": "eslint src/",
42
- "format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
43
- "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"",
42
+ "format": "prettier --write \"src/**/*.{ts,tsx,css}\" \".storybook/**/*.{ts,tsx}\"",
43
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\" \".storybook/**/*.{ts,tsx}\"",
44
44
  "typecheck": "tsc --noEmit",
45
+ "storybook": "storybook dev -p 6006",
46
+ "build-storybook": "storybook build",
45
47
  "test": "vitest run",
46
48
  "test:coverage": "vitest run --coverage",
47
49
  "test:watch": "vitest",
@@ -52,11 +54,14 @@
52
54
  "@radix-ui/react-switch": "^1.3.1",
53
55
  "@radix-ui/react-toggle": "^1.1.12",
54
56
  "@radix-ui/react-toggle-group": "^1.1.13",
57
+ "@radix-ui/react-tooltip": "^1.2.16",
55
58
  "ajv": "^8.17.1",
56
59
  "ajv-formats": "^2.1.1",
57
60
  "class-variance-authority": "^0.7.1",
58
61
  "clsx": "^2.1.1",
59
62
  "lucide-react": "^0.462.0",
63
+ "marked": "^18.0.11",
64
+ "mthds": "^0.25.0",
60
65
  "react-dropzone": "^14.3.8",
61
66
  "tailwind-merge": "^2.6.0"
62
67
  },
@@ -74,18 +79,27 @@
74
79
  },
75
80
  "devDependencies": {
76
81
  "@eslint/js": "^9.39.4",
82
+ "@storybook/addon-a11y": "^10.5.10",
83
+ "@storybook/addon-docs": "^10.5.10",
84
+ "@storybook/addon-vitest": "^10.5.10",
85
+ "@storybook/react-vite": "^10.5.10",
77
86
  "@testing-library/jest-dom": "^7.0.1",
78
87
  "@testing-library/react": "^16.3.2",
79
88
  "@testing-library/user-event": "^14.6.6",
80
89
  "@types/node": "^22",
81
90
  "@types/react": "^19",
82
91
  "@types/react-dom": "^19.2.3",
92
+ "@vitejs/plugin-react": "^5.2.0",
93
+ "@vitest/browser-playwright": "^4.1.11",
83
94
  "@vitest/coverage-v8": "^4.1.0",
84
95
  "eslint": "^9.39.4",
96
+ "eslint-plugin-storybook": "^10.5.10",
85
97
  "jsdom": "^30.0.1",
98
+ "playwright": "^1.62.1",
86
99
  "prettier": "^3.8.1",
87
100
  "react": "^19",
88
101
  "react-dom": "^19",
102
+ "storybook": "^10.5.10",
89
103
  "tailwindcss": "^3.4.17",
90
104
  "tailwindcss-animate": "^1.0.7",
91
105
  "tsup": "^8.5.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/descriptor.ts"],"names":[],"mappings":";AAkKO,SAAS,gBAAgB,KAAA,EAAkC;AAChE,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,MAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,UAAA;AAAA,IACT,KAAK,OAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,SAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT;AACE,MAAA,OAAO,YAAA;AAAA;AAEb","file":"chunk-6XD6UZSU.js","sourcesContent":["/**\n * The `RunField` descriptor - the consumer-facing currency of the form kernel.\n *\n * A method's inputs arrive from the API as a map of variable name →\n * `PipeInputContract` ({ concept_ref, json_schema }). That JSON Schema is rich\n * (Pydantic-generated) and not pleasant to render directly. `buildRunFields`\n * (in `derive.ts`) normalizes it once into a flat, recursive `RunField[]`\n * descriptor that the presentational field components consume - so the\n * components never touch raw JSON Schema, and stories can describe any input\n * shape declaratively.\n *\n * Pure module: no React, no API calls. Trivially unit-testable.\n */\n\nexport type RunFieldKind =\n | 'text' // short single-line string\n | 'prose' // long free-text (textarea)\n | 'date' // a calendar date (schema `format: date` or `date-time`)\n | 'number' // integer or float\n | 'boolean' // true/false\n | 'enum' // pick one of a fixed set\n | 'document' // a file (PDF, docx…) by upload or URL\n | 'image' // a file rendered with a preview\n | 'object' // a structured concept with nested fields\n | 'list' // an array of one element type\n | 'unknown'; // anything we can't map → raw JSON escape hatch\n\nexport interface RunFieldCommon {\n /** The variable identifier as written in the method (rendered in mono). */\n name: string;\n /** Human label; falls back to `name` when absent. */\n title?: string;\n /** The concept this input carries, e.g. `native.Document`, `demo.Invoice`. */\n conceptRef?: string;\n /** One-line helper text shown under the label. */\n description?: string;\n /** Required inputs always show; optional ones can collapse. */\n required: boolean;\n /**\n * Whether Run waits for this input - set on TOP-LEVEL fields only, straight\n * from `inputMustBeFilled` (see `mustBeFilled` in `readiness.ts` for why this\n * is not the same question as `required`). Nested fields leave it undefined;\n * they are gated through their parent's `fieldFilled`.\n */\n gating?: boolean;\n /**\n * The single property this field's value sits inside on the wire, when its\n * concept declares a scalar content model: `native.Text` is `TextContent\n * {text}`, `native.Number` is `NumberContent {number}`, `native.YesNo` is\n * `YesNoContent {yes_no}`. The control still holds the plain scalar; the\n * value bridge wraps into this property on the way out and unwraps on the way\n * back in.\n *\n * A property NAME, never a schema - the descriptor stays the only currency\n * and `buildRunFields` stays the only reader of JSON Schema. Absent whenever\n * the value is already the whole content (a structured concept, a file, a\n * child property of a structure): wrapping those would double-nest them.\n */\n contentKey?: string;\n}\n\nexport interface TextRunField extends RunFieldCommon {\n kind: 'text';\n placeholder?: string;\n}\n\nexport interface ProseRunField extends RunFieldCommon {\n kind: 'prose';\n placeholder?: string;\n}\n\nexport interface DateRunField extends RunFieldCommon {\n kind: 'date';\n /**\n * True when the backing schema is `format: date-time`: the stored value is a\n * full RFC 3339 timestamp (`2026-07-06T00:00:00Z`) so it passes the API's\n * `date-time` validation, even though the control only asks for a day. False\n * for a bare `format: date`, where the value stays `YYYY-MM-DD`.\n */\n datetime: boolean;\n}\n\nexport interface NumberRunField extends RunFieldCommon {\n kind: 'number';\n integer: boolean;\n min?: number;\n max?: number;\n}\n\nexport interface BooleanRunField extends RunFieldCommon {\n kind: 'boolean';\n}\n\nexport interface EnumRunField extends RunFieldCommon {\n kind: 'enum';\n options: string[];\n}\n\nexport interface FileRunField extends RunFieldCommon {\n kind: 'document' | 'image';\n /** Accept hint shown to the user, e.g. \"PDF, PNG, JPG\". */\n accept?: string;\n}\n\nexport interface ObjectRunField extends RunFieldCommon {\n kind: 'object';\n fields: RunField[];\n}\n\nexport interface ListRunField extends RunFieldCommon {\n kind: 'list';\n /** The element descriptor (its `name` is unused; the index labels items). */\n item: RunField;\n /**\n * The FEWEST items the slot accepts, when the schema states a lower bound.\n * Absent for a variable `Concept[]` list, which demands none.\n *\n * Read off the array schema's `minItems` rather than off the contract's\n * `item_count`, which states the same number: this exists so `fieldFilled` can\n * answer the question **ajv** answers, and `minItems` is the keyword ajv\n * reads. pipelex emits `minItems`/`maxItems` = N for a `[N]` slot and neither\n * for `[]`, so on a top-level slot the two sources agree by construction.\n *\n * A schema may still state a lower bound alone - `mapSchema` recurses, so a\n * nested array inside a structured concept reaches here with whatever its\n * model declared and no MTHDS multiplicity behind it. Gating on that bound is\n * the same rule, and it is the direction that cannot leave readiness more\n * permissive than the gate.\n */\n itemCount?: number;\n /**\n * The MOST items the slot accepts, off the schema's `maxItems`.\n *\n * A separate field because it is a separate fact, and conflating them is a\n * bug that hides: `itemCount` was read as a minimum by readiness and as a\n * maximum by the control that stops offering `Add`, which agree only while\n * a contract states both bounds equal. A list told \"at least two\" was then\n * presented as a list of exactly two.\n */\n maxItemCount?: number;\n}\n\nexport interface UnknownRunField extends RunFieldCommon {\n kind: 'unknown';\n}\n\nexport type RunField =\n | TextRunField\n | ProseRunField\n | DateRunField\n | NumberRunField\n | BooleanRunField\n | EnumRunField\n | FileRunField\n | ObjectRunField\n | ListRunField\n | UnknownRunField;\n\n/** The short, friendly category label for a concept_ref (drives the pill dot). */\nexport type ConceptCategory =\n 'text' | 'date' | 'document' | 'image' | 'number' | 'boolean' | 'choice' | 'structured' | 'list';\n\nexport function conceptCategory(field: RunField): ConceptCategory {\n switch (field.kind) {\n case 'text':\n case 'prose':\n return 'text';\n case 'date':\n return 'date';\n case 'document':\n return 'document';\n case 'image':\n return 'image';\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'enum':\n return 'choice';\n case 'list':\n return 'list';\n default:\n return 'structured';\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/wire-format.ts"],"names":[],"mappings":"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","file":"chunk-7BMOPXDY.js","sourcesContent":["/**\n * Converts between the simplified inputs.json format and the full RJSF form format.\n *\n * The inputs.json file uses a SIMPLIFIED format for users:\n * - Text: \"my text\" (instead of { text: \"my text\" })\n * - Document: \"file.pdf\" or { url: \"...\" } (instead of { url: \"...\", ... })\n * - Image: same as Document\n * - Text[]: [\"t1\", \"t2\"]\n * - Document[]: [\"f1.pdf\"] or [{ url: \"...\" }]\n * - Custom: { concept, content } (no simplification)\n *\n * The RJSF form uses the FULL concept structure from the json_schema.\n *\n * Two directions:\n * - deflate: form (full) → inputs.json (simplified) - for writing inputs.json / API calls\n * - inflate: inputs.json (simplified) → form (full) - for populating the form from inputs.json\n */\n\nimport { asCalendarDate } from './date-format';\nimport { isWireDocumentLikeConcept, isWireTextConcept, splitListConcept } from './native-concepts';\nimport { hasOwnProp, ownProp } from './own-property';\nimport { collectSchemaDefs, resolveSchemaIndirection, schemaTypeOf } from './schema-utils';\n\n/** The wire-format view of the native-concept taxonomy (which concept codes use\n * simplified formats) lives in `native-concepts.ts` - including the record of\n * where it drifts from the field mapper's view. */\nfunction isListConcept(conceptCode: string): { isList: boolean; baseConcept: string } {\n const { base, isList } = splitListConcept(conceptCode);\n return { isList, baseConcept: base ?? '' };\n}\n\nconst isTextConcept = isWireTextConcept;\nconst isDocumentLikeConcept = isWireDocumentLikeConcept;\n\n// ─── Deflate: form (full) → inputs.json (simplified) ──────────────────────\n\n/**\n * Convert a single form value to the simplified inputs.json format.\n * Used when writing inputs.json and when calling the run API.\n *\n * Rules:\n * - Text { text: \"hello\" } → \"hello\"\n * - Document { url: \"file.pdf\", ... } → \"file.pdf\" (if only url) or { url, ... }\n * - Image: same as Document\n * - Page: same as Document\n * - List types → array of deflated items\n * - Custom → { concept, content }\n */\nexport function deflateInput(value: unknown, conceptCode: string): unknown {\n const { isList, baseConcept } = isListConcept(conceptCode);\n\n if (isList) {\n const items = Array.isArray(value) ? value : [];\n // pipelex accepts Sequence[str] for list inputs, not list of dicts.\n // Always simplify list items to their scalar form (URL string for docs, plain string for text).\n return items.map((item) => deflateListItem(item, baseConcept));\n }\n\n return deflateSingleValue(value, baseConcept);\n}\n\n/** Deflate a single item within a list - always reduces to the simplest scalar form. */\nfunction deflateListItem(value: unknown, concept: string): unknown {\n if (isTextConcept(concept)) {\n if (value && typeof value === 'object' && 'text' in value) {\n return (value as { text: string }).text;\n }\n return typeof value === 'string' ? value : String(value ?? '');\n }\n\n if (isDocumentLikeConcept(concept)) {\n // Always extract just the URL for list items - pipelex resolves metadata at runtime\n if (value && typeof value === 'object' && 'url' in value) {\n return (value as { url: string }).url;\n }\n if (typeof value === 'string') return value;\n return '';\n }\n\n // Custom structured concept → { concept, content }.\n //\n // IDEMPOTENT ON PURPOSE - see `unwrapAllWrappers`. Wrapping unconditionally\n // corrupted persisted inputs: a host panel seeds the form with the RAW\n // stored value when the input schemas aren't loaded yet (no dry run yet),\n // so the form could hold an ALREADY-wrapped value; the next change deflated\n // it again and saved `{ concept, content: { concept, content: {...} } }`.\n // Wrapping exactly once, whatever we're handed, makes that unreachable.\n return { concept, content: unwrapAllWrappers(value) };\n}\n\nfunction deflateSingleValue(value: unknown, concept: string): unknown {\n if (isTextConcept(concept)) {\n // { text: \"hello\" } → \"hello\"\n if (value && typeof value === 'object' && 'text' in value) {\n return (value as { text: string }).text;\n }\n // Already a string (passthrough)\n return typeof value === 'string' ? value : String(value ?? '');\n }\n\n if (isDocumentLikeConcept(concept)) {\n // Always extract just the URL - pipelex resolves metadata at runtime.\n // A bare dict without a 'concept' key is rejected by StuffFactory.\n if (value && typeof value === 'object' && 'url' in value) {\n return (value as { url: string }).url;\n }\n // Already a string URL (passthrough)\n if (typeof value === 'string') return value;\n return '';\n }\n\n // Custom structured concept → { concept, content }.\n //\n // IDEMPOTENT ON PURPOSE - see `unwrapAllWrappers`. Wrapping unconditionally\n // corrupted persisted inputs: a host panel seeds the form with the RAW\n // stored value when the input schemas aren't loaded yet (no dry run yet),\n // so the form could hold an ALREADY-wrapped value; the next change deflated\n // it again and saved `{ concept, content: { concept, content: {...} } }`.\n // Wrapping exactly once, whatever we're handed, makes that unreachable.\n return { concept, content: unwrapAllWrappers(value) };\n}\n\n// ─── Inflate: inputs.json (simplified) → form (full) ──────────────────────\n\n/**\n * Convert a simplified inputs.json value to the full form structure.\n * Used when populating the RJSF form from inputs.json.\n *\n * Rules:\n * - \"hello\" → { text: \"hello\" } (for Text concepts)\n * - \"file.pdf\" → { url: \"file.pdf\" } (for Document/Image/Page concepts)\n * - { url: \"...\" } → passthrough (already full)\n * - [\"t1\", \"t2\"] → inflated array of items\n * - { concept, content } → content (for custom concepts)\n */\nexport function inflateInput(value: unknown, conceptCode: string): unknown {\n const { isList, baseConcept } = isListConcept(conceptCode);\n\n if (isList) {\n // The sandbox may write the wrapped form at the LIST level:\n // { concept: \"native.Document\", content: [item, item] } - pipelex accepts it.\n // Unwrap before the array check, otherwise the wrapper itself gets treated\n // as a single list item and inflates to one empty entry.\n const unwrapped = isWrappedForm(value) ? value.content : value;\n // Handle: array (correct), single object (legacy/form default), or null/undefined\n let items: unknown[];\n if (Array.isArray(unwrapped)) {\n items = unwrapped;\n } else if (unwrapped != null && typeof unwrapped === 'object') {\n // Single object instead of array (e.g., {\"url\": \"\"} from form default) - wrap it\n items = [unwrapped];\n } else {\n items = [];\n }\n return items.map((item) => inflateSingleValue(item, baseConcept));\n }\n\n return inflateSingleValue(value, baseConcept);\n}\n\n/** Known optional fields on DocumentContent (from pipelex Pydantic model). */\nconst DOCUMENT_FIELDS = new Set(['url', 'public_url', 'mime_type', 'filename', 'title', 'snippet']);\n\n/** Returns true if the object looks like a DocumentContent (has any known doc field). */\nfunction looksLikeDocument(obj: Record<string, unknown>): boolean {\n return Object.keys(obj).some((k) => DOCUMENT_FIELDS.has(k));\n}\n\n/**\n * Detect the fully-qualified wrapper form `{ concept: \"...\", content: ... }`.\n * pipelex accepts this for any concept (native or custom), and the mthds-inputs\n * agent skill writes it by default for disambiguation. We unwrap before applying\n * concept-specific inflation so the form populates correctly.\n */\nfunction isWrappedForm(value: unknown): value is { concept: string; content: unknown } {\n return (\n !!value &&\n typeof value === 'object' &&\n 'concept' in value &&\n 'content' in value &&\n typeof (value as { concept: unknown }).concept === 'string'\n );\n}\n\nfunction inflateSingleValue(value: unknown, concept: string): unknown {\n // Unwrap { concept, content } for native concepts - the content IS the value.\n // For custom concepts we unwrap below (historical behaviour) but after concept-specific checks.\n if (isWrappedForm(value) && (isTextConcept(concept) || isDocumentLikeConcept(concept))) {\n return inflateSingleValue(value.content, concept);\n }\n\n if (isTextConcept(concept)) {\n // \"hello\" → { text: \"hello\" }\n if (typeof value === 'string') {\n return { text: value };\n }\n // Already full structure { text: \"...\" }\n if (value && typeof value === 'object' && 'text' in value) {\n return value;\n }\n return { text: '' };\n }\n\n if (isDocumentLikeConcept(concept)) {\n // \"file.pdf\" → { url: \"file.pdf\" }\n if (typeof value === 'string') {\n return { url: value };\n }\n // Already full structure { url: \"...\" }\n if (value && typeof value === 'object' && 'url' in value) {\n return value;\n }\n // Object without url key but with other document fields (e.g. from RJSF defaults)\n // Ensure the required url field is present\n if (value && typeof value === 'object' && looksLikeDocument(value as Record<string, unknown>)) {\n return { ...(value as Record<string, unknown>), url: '' };\n }\n return { url: '' };\n }\n\n // Custom structured: unwrap { concept, content } → content.\n //\n // Unwrap REPEATEDLY. `deflateSingleValue` used to wrap unconditionally, so a\n // form change made while the input schemas weren't loaded yet re-wrapped an\n // already-wrapped value and persisted `{ concept, content: { concept,\n // content: {...} } }` to DynamoDB. Unwrapping a single level left the FORM\n // holding `{ concept, content }` - properties no schema declares, so RJSF\n // matched nothing and rendered every field empty, with the real values\n // sitting one level deeper. Deflate is idempotent now, but the corrupted\n // shape survives in persisted inputData, so this heals it on read.\n return unwrapAllWrappers(value);\n}\n\n/** Strip every `{ concept, content }` layer - one, or the double wrap a\n * non-idempotent deflate persisted. */\nfunction unwrapAllWrappers(value: unknown): unknown {\n let current = value;\n while (isWrappedForm(current)) {\n current = current.content;\n }\n // A `{ content }` with no `concept` is the historical half-wrapper.\n if (current && typeof current === 'object' && !Array.isArray(current) && 'content' in current) {\n return (current as { content: unknown }).content;\n }\n return current;\n}\n\n// ─── Schema helpers ─────────────────────────────────────────────────────\n\ninterface InputSchema {\n concept_ref: string;\n json_schema?: Record<string, unknown>;\n}\n\n/**\n * The validation API returns concept_ref WITHOUT the [] suffix for list inputs.\n * The array-ness is only encoded in json_schema.type === \"array\".\n * This helper resolves the correct concept ref by checking the schema.\n */\nexport function resolveConceptCode(schema: InputSchema): string {\n const code = schema.concept_ref;\n // Defensive: a malformed/partial contract entry (missing concept) must\n // degrade, never throw and blank the whole input panel.\n if (!code) return '';\n if (!code.endsWith('[]') && (schema.json_schema as Record<string, unknown>)?.type === 'array') {\n return code + '[]';\n }\n return code;\n}\n\n// ─── Batch helpers for full inputData objects ────────────────────────────\n\n/**\n * Deflate all inputs from form format to simplified inputs.json format.\n * Used by InputConfigPanel when preparing data for the run API.\n */\nexport function deflateAllInputs(\n formData: Record<string, unknown>,\n inputSchemas: Record<string, InputSchema>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [stuffName, schema] of Object.entries(inputSchemas)) {\n result[stuffName] = deflateInput(ownProp(formData, stuffName), resolveConceptCode(schema));\n }\n return result;\n}\n\n/**\n * Heal values against their json_schema: the run-form bridge used to\n * double-wrap plain string properties as `{ text: \"...\" }` (fixed in\n * run-values.ts, but the corrupted shape survives in persisted inputData -\n * store and server copies). Wherever the schema expects a string but the\n * value is a lone `{ text: string }` wrapper, unwrap it. Walks nested\n * objects and arrays, resolving `#/$defs/...` refs against the root schema;\n * anything already valid passes through untouched.\n */\nexport function healStringWrappers(\n value: unknown,\n rawSchema: Record<string, unknown> | undefined,\n defs?: Record<string, Record<string, unknown>>,\n): unknown {\n if (!rawSchema || value == null) return value;\n\n // Resolve $ref / nullable-anyOf indirection (Pydantic emits `{$ref}` for\n // nested models and `anyOf: [T, {type:'null'}]` for optionals). The `$defs`\n // walk deliberately keeps its historical no-array-traversal mode - see\n // `CollectDefsOptions` in schema-utils.\n const allDefs = defs ?? collectSchemaDefs(rawSchema, {}, { traverseArrays: false });\n const schema = resolveSchemaIndirection(rawSchema, allDefs);\n const type = schemaTypeOf(schema);\n\n // A `format: date` field takes a calendar date ALONE. `DateContent` in pipelex\n // enforces that with a `mode=\"before\"` validator (`_reject_lax_temporal`) that\n // deliberately closes pydantic's lax coercion - a datetime string on `date`\n // would silently drop its time and offset (DT3, \"no silent midnight\"), so the\n // runner answers a 500, not a coercion.\n //\n // An agent-written or hand-written inputs.json says `\"2026-07-06T00:00:00Z\"`\n // anyway - that is how every system exports a date. So NORMALIZE it here to\n // the day it denotes rather than forwarding it to fail at the runner: the\n // padding is noise, and dropping noise is not the fidelity loss DT3 forbids.\n // A value carrying a REAL time (15:40) returns null and is left untouched -\n // it must fail, because silently discarding it is precisely the corruption\n // the rule exists to prevent.\n if (type === 'string' && schema.format === 'date' && typeof value === 'string') {\n return asCalendarDate(value) ?? value;\n }\n\n if (type === 'string') {\n if (\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value).length === 1 &&\n typeof (value as { text?: unknown }).text === 'string'\n ) {\n return (value as { text: string }).text;\n }\n return value;\n }\n if (type === 'object' && typeof value === 'object' && !Array.isArray(value)) {\n const props = schema.properties as Record<string, Record<string, unknown>> | undefined;\n if (!props) return value;\n const out = { ...(value as Record<string, unknown>) };\n for (const [key, propSchema] of Object.entries(props)) {\n if (hasOwnProp(out, key)) out[key] = healStringWrappers(out[key], propSchema, allDefs);\n }\n return out;\n }\n if (type === 'array' && Array.isArray(value)) {\n const items = schema.items as Record<string, unknown> | undefined;\n return value.map((item) => healStringWrappers(item, items, allDefs));\n }\n return value;\n}\n\n/** Nothing left worth sending, once this value has itself been pruned. */\nfunction isEmptyAfterPruning(value: unknown): boolean {\n if (value === '' || value === null || value === undefined) return true;\n // An object whose every property was itself pruned away carries nothing, and\n // that is what an untouched OPTIONAL STRUCTURED input looks like by the time\n // it reaches here - a shell of empty children, emptied out. Keeping the `{}`\n // handed it to ajv against the concept's full schema, which rejected the run\n // for a required child of an input the method said may be omitted. Dropping\n // it is the same judgement the wire payload already makes one step later\n // (`apiInputsFromSchemaData` omits it as unfilled); making the prune agree is\n // what stops the gate from failing a run it was about to omit anyway.\n //\n // An empty ARRAY is deliberately NOT empty: a plural slot is never absent in\n // MTHDS - its empty form IS the empty list - so dropping it would invent an\n // absence the method cannot express.\n return typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0;\n}\n\n/**\n * Drop optional properties the user never filled, so an untouched field cannot\n * fail validation or reach the API as an empty string.\n *\n * RJSF fills EVERY unset string property with `\"\"` on mount. That is harmless\n * for a plain string, but `prepareSchemaForRjsf` collapses pydantic's\n * `anyOf: [T, null]` by dropping the null branch, so an optional *constrained*\n * field - `DateContent.time`, declared `datetime.time | None` and rendered\n * `{ type: \"string\", format: \"time\" }` - is left demanding a well-formed time.\n * `\"\"` is not one, and the run was blocked on a field the user never opened.\n *\n * Pruning is the semantically correct repair, not a validation dodge: for\n * pipelex an absent optional field IS `None`, and `\"\"` would fail pydantic at\n * the runner just as it fails ajv here. Only properties absent from their\n * parent's `required` are dropped - an empty REQUIRED field must still fail, so\n * the user is told about it.\n *\n * What counts as empty is `isEmptyAfterPruning`, and it includes an optional\n * STRUCTURE the user never opened, on exactly the same grounds.\n */\nexport function pruneEmptyOptionals(\n value: unknown,\n rawSchema: Record<string, unknown> | undefined,\n defs?: Record<string, Record<string, unknown>>,\n): unknown {\n if (!rawSchema || value == null) return value;\n\n const allDefs = defs ?? collectSchemaDefs(rawSchema, {}, { traverseArrays: false });\n const schema = resolveSchemaIndirection(rawSchema, allDefs);\n const type = schemaTypeOf(schema);\n\n if (type === 'array' && Array.isArray(value)) {\n const items = schema.items as Record<string, unknown> | undefined;\n return value.map((item) => pruneEmptyOptionals(item, items, allDefs));\n }\n if (type !== 'object' || typeof value !== 'object' || Array.isArray(value)) return value;\n\n const props = schema.properties as Record<string, Record<string, unknown>> | undefined;\n if (!props) return value;\n const required = new Set(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n const out: Record<string, unknown> = {};\n for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n const propSchema = ownProp(props, key);\n if (!propSchema) {\n out[key] = raw;\n continue;\n }\n const pruned = pruneEmptyOptionals(raw, propSchema, allDefs);\n if (isEmptyAfterPruning(pruned) && !required.has(key)) continue;\n out[key] = pruned;\n }\n return out;\n}\n\n/**\n * Inflate all inputs from simplified inputs.json format to form format.\n * Used by onInputUpdate when receiving inputs.json changes from the sandbox.\n */\nexport function inflateAllInputs(\n simplifiedData: Record<string, unknown>,\n inputSchemas: Record<string, InputSchema>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [stuffName, value] of Object.entries(simplifiedData)) {\n const schema = ownProp(inputSchemas, stuffName);\n if (schema) {\n result[stuffName] = healStringWrappers(\n inflateInput(value, resolveConceptCode(schema)),\n schema.json_schema,\n );\n } else {\n // Unknown input - pass through unchanged\n result[stuffName] = value;\n }\n }\n return result;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/contracts.ts"],"names":[],"mappings":";;;AAiFO,SAAS,YAAA,CAAa,QAAgB,QAAA,EAA0B;AACrE,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AAC9B;AAkBO,SAAS,iBAAA,CACd,eAAA,EACA,MAAA,EACA,QAAA,EAC4B;AAC5B,EAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,QAAA,EAAU,OAAO,MAAA;AAC1C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,QAAQ,OAAA,CAAQ,eAAA,EAAiB,YAAA,CAAa,MAAA,EAAQ,QAAQ,CAAC,CAAA;AACrE,IAAA,IAAI,OAAO,OAAO,KAAA;AAAA,EACpB;AACA,EAAA,OAAO,OAAA,CAAQ,iBAAiB,QAAQ,CAAA;AAC1C;AAWO,SAAS,gBAAgB,KAAA,EAAmC;AACjE,EAAA,OAAO,MAAM,QAAA,KAAa,UAAA;AAC5B;AAcO,SAAS,cAAc,KAAA,EAAmC;AAC/D,EAAA,OAAQ,KAAA,CAAM,aAAgD,IAAA,KAAS,OAAA;AACzE;AASO,SAAS,kBAAkB,KAAA,EAAmC;AACnE,EAAA,OAAO,MAAM,YAAA,KAAiB,OAAA;AAChC;AAqBO,SAAS,kBAAkB,KAAA,EAAmC;AACnE,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,OAAO,KAAA;AACnC,EAAA,OAAO,CAAC,aAAA,CAAc,KAAK,CAAA,IAAK,kBAAkB,KAAK,CAAA;AACzD","file":"chunk-HARYEWNG.js","sourcesContent":["/**\n * The typed `pipe_io_contracts` mirror and its gating predicates.\n *\n * Mirrors pipelex's `PipeIOContract` (pipelex/pipeline/pipe_io_contracts.py).\n * The SDK deliberately keeps `pipe_io_contracts` opaque, so the kernel is the\n * canonical TS home for this shape until the D-track specs it.\n *\n * The map itself is keyed by namespaced pipe ref (`<domain>.<pipe_code>`),\n * NOT bare pipe code - use `getPipeIOContract` to look entries up by the bare\n * codes the UI tracks.\n */\n\nimport { ownProp } from './own-property';\n\n/**\n * The authored presence marker on an input slot, verbatim.\n *\n * - `plain` - no marker: the caller must supply the input.\n * - `optional` (`?`) - the caller may omit it and the pipe handles the absence\n * itself.\n * - `force` (`!`) - a use-site assertion that the value IS present. It must be\n * supplied, exactly like `plain`; the distinction is the authored assertion,\n * which lint and graph surfaces read and a form does not.\n */\nexport type InputPresence = 'plain' | 'optional' | 'force';\n\n/**\n * How many items a slot carries.\n *\n * - `single` - one item. `Concept[1]` is single too: no list framing.\n * - `variable` (`Concept[]`) - a list of any length, the empty list included.\n * - `fixed` (`Concept[N]`, N > 1) - a list of exactly `item_count` items.\n */\nexport type IOMultiplicity = 'single' | 'variable' | 'fixed';\n\nexport interface PipeInputContract {\n concept_ref: string;\n /** The declared presence marker - see `InputPresence`. */\n presence: InputPresence;\n /** The declared multiplicity - see `IOMultiplicity`. */\n multiplicity: IOMultiplicity;\n /**\n * The exact item count, non-null exactly when `multiplicity` is `fixed`. The\n * slot is always on the wire, `null` off the fixed arm.\n */\n item_count: number | null;\n /**\n * The input's JSON Schema. A plural slot (`variable` or `fixed`) is an array\n * wrapper around the item schema, and a `fixed` one additionally carries\n * `minItems` / `maxItems` set to `item_count` - which is what makes the gate's\n * ajv pass enforce the declared count without the kernel restating it.\n */\n json_schema: Record<string, unknown>;\n}\n\nexport interface PipeOutputContract {\n concept_ref: string;\n multiplicity: IOMultiplicity;\n /** As on the input: non-null exactly on the `fixed` arm, always on the wire. */\n item_count: number | null;\n /**\n * `true` when the output is declared optional (`?`) - the pipe may resolve it\n * as a recorded absence instead of a value.\n *\n * Deliberately still a boolean while the INPUT side carries three-valued\n * `presence`: output presence is genuinely two-valued, because `!` is\n * rejected on an output. The asymmetry is the wire's, not ours.\n */\n optional: boolean;\n}\n\nexport interface PipeIOContract {\n inputs: Record<string, PipeInputContract>;\n output: PipeOutputContract;\n}\n\n/** The `pipe_io_contracts` map: namespaced `pipe_ref` → IO contract. */\nexport type PipeIOContracts = Record<string, PipeIOContract>;\n\n/** Namespaced pipe ref (`<domain>.<pipe_code>`) - the identity convention the\n * validate artifacts key on. */\nexport function buildPipeRef(domain: string, pipeCode: string): string {\n return `${domain}.${pipeCode}`;\n}\n\n/**\n * Look up a pipe's IO contract by pipe code, tolerant of both key conventions.\n *\n * The map may be keyed by namespaced `pipe_ref` (`<domain>.<code>`, the\n * canonical convention) OR by bare pipe code - the current hosted `/validate`\n * keys `pipe_structures` by bare code, and methods persisted before the\n * pipe_ref re-keying also carry bare-code keys. Try the namespaced ref first\n * (when the caller supplies a domain), then fall back to the bare code.\n * Returns `undefined` (never crashes) when neither matches.\n *\n * Both lookups read OWN properties only. A bare index returned the inherited\n * `Object` constructor for a pipe code named `constructor` (or `toString`, …) -\n * a truthy non-contract that sailed straight through the `if (!contract)` guard\n * hosts are shown writing, so a pipe that does not exist rendered as one taking\n * no inputs instead of reaching the host's not-found path. See `ownProp`.\n */\nexport function getPipeIOContract(\n pipeIoContracts: PipeIOContracts | null | undefined,\n domain: string | null | undefined,\n pipeCode: string | null | undefined,\n): PipeIOContract | undefined {\n if (!pipeIoContracts || !pipeCode) return undefined;\n if (domain) {\n const byRef = ownProp(pipeIoContracts, buildPipeRef(domain, pipeCode));\n if (byRef) return byRef;\n }\n return ownProp(pipeIoContracts, pipeCode);\n}\n\n/**\n * True when the method declared the input omittable (`?`).\n *\n * The ONE reader of `presence` in the package: everything that asks \"may this\n * be absent?\" - the descriptor's `required`, the gate's `required` list, the\n * payload builders that omit an unfilled input - goes through here, so a\n * marker the wire adds later cannot mean one thing on one surface and another\n * elsewhere. `force` (`!`) reads as NOT optional, like `plain`.\n */\nexport function isOptionalInput(input: PipeInputContract): boolean {\n return input.presence === 'optional';\n}\n\n/**\n * True when the input carries a plural concept (`Image[]`, `Image[3]`): its\n * JSON Schema is an array wrapper.\n *\n * Deliberately a SCHEMA test rather than a read of the declared `multiplicity`,\n * even though the wire now states both. The schema is what `buildRunFields`\n * maps and therefore what the user is shown; a predicate reading the other\n * field could disagree with the rendered control, which is the exact failure\n * mode `mustBeFilled` (readiness.ts) exists to prevent. The two agree by\n * construction upstream - pipelex wraps the schema in an array exactly when it\n * reports `variable` or `fixed`.\n */\nexport function isPluralInput(input: PipeInputContract): boolean {\n return (input.json_schema as { type?: unknown } | undefined)?.type === 'array';\n}\n\n/**\n * True when the slot declares an EXACT number of items (`Concept[N]`), whose\n * count is `item_count`.\n *\n * The distinction that matters to the gate: a variable list can legitimately be\n * empty, a fixed one cannot.\n */\nexport function isFixedCountInput(input: PipeInputContract): boolean {\n return input.multiplicity === 'fixed';\n}\n\n/**\n * True when the user MUST put a value in before a run can start.\n *\n * Two declarations relieve an input of that duty, for different reasons:\n * - **optional (`?`)** - the method itself states the caller may omit it;\n * - **variable-plural (`[]`)** - the empty list is a legitimate value and the\n * language cannot declare \"at least one\", so gating on it would invent a\n * constraint the method never made.\n *\n * Everything else gates: `plain`, `force` (`!`), and a **fixed-count** list\n * (`[N]`), which is a list whose empty form the method has explicitly ruled out.\n * This is the derivation the input-form descriptor spec states for `gating`.\n *\n * Emptiness is all this predicate answers for - WHETHER a slot gates, never how\n * much it needs. A fixed-count list that holds fewer items than it declares\n * gates here and is refused by `fieldFilled`, which reads the declared count off\n * the descriptor's `itemCount`, and by the gate's ajv pass on the schema's\n * `minItems`. All three read the one number the method stated.\n */\nexport function inputMustBeFilled(input: PipeInputContract): boolean {\n if (isOptionalInput(input)) return false;\n return !isPluralInput(input) || isFixedCountInput(input);\n}\n"]}
@@ -1,40 +0,0 @@
1
- // src/core/native-concepts.ts
2
- function nativeSet(...names) {
3
- return new Set(names.flatMap((n) => [n, `native.${n}`]));
4
- }
5
- var TEXT_CONCEPTS = nativeSet("Text");
6
- var DATE_CONCEPTS = nativeSet("Date");
7
- var HTML_CONCEPTS = nativeSet("HTML");
8
- var DOCUMENT_CONCEPTS = nativeSet("Document");
9
- var PAGE_CONCEPTS = nativeSet("Page");
10
- var IMAGE_CONCEPTS = nativeSet("Image");
11
- var NUMBER_CONCEPTS = nativeSet("Number");
12
- var YES_NO_CONCEPTS = nativeSet("YesNo");
13
- var FIELD_TEXT_CONCEPTS = /* @__PURE__ */ new Set([
14
- ...TEXT_CONCEPTS,
15
- ...DATE_CONCEPTS
16
- ]);
17
- var FIELD_DOCUMENT_CONCEPTS = /* @__PURE__ */ new Set([
18
- ...DOCUMENT_CONCEPTS,
19
- ...PAGE_CONCEPTS
20
- ]);
21
- function isWireTextConcept(concept) {
22
- return TEXT_CONCEPTS.has(concept);
23
- }
24
- function isWireDocumentLikeConcept(concept) {
25
- return DOCUMENT_CONCEPTS.has(concept) || IMAGE_CONCEPTS.has(concept) || PAGE_CONCEPTS.has(concept);
26
- }
27
- var TEXT_WRAPPER_CONCEPTS = /* @__PURE__ */ new Set([
28
- ...TEXT_CONCEPTS,
29
- ...DATE_CONCEPTS,
30
- ...HTML_CONCEPTS
31
- ]);
32
- function splitListConcept(conceptRef) {
33
- if (!conceptRef) return { isList: false };
34
- if (conceptRef.endsWith("[]")) return { base: conceptRef.slice(0, -2), isList: true };
35
- return { base: conceptRef, isList: false };
36
- }
37
-
38
- export { DATE_CONCEPTS, DOCUMENT_CONCEPTS, FIELD_DOCUMENT_CONCEPTS, FIELD_TEXT_CONCEPTS, HTML_CONCEPTS, IMAGE_CONCEPTS, NUMBER_CONCEPTS, PAGE_CONCEPTS, TEXT_CONCEPTS, TEXT_WRAPPER_CONCEPTS, YES_NO_CONCEPTS, isWireDocumentLikeConcept, isWireTextConcept, splitListConcept };
39
- //# sourceMappingURL=chunk-NMT7BRLO.js.map
40
- //# sourceMappingURL=chunk-NMT7BRLO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/native-concepts.ts"],"names":[],"mappings":";AAqCA,SAAS,aAAa,KAAA,EAAsC;AAC1D,EAAA,OAAO,IAAI,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,CAAA,OAAA,EAAU,CAAC,CAAA,CAAE,CAAC,CAAC,CAAA;AACzD;AAEO,IAAM,aAAA,GAAgB,UAAU,MAAM;AACtC,IAAM,aAAA,GAAgB,UAAU,MAAM;AAEtC,IAAM,aAAA,GAAgB,UAAU,MAAM;AACtC,IAAM,iBAAA,GAAoB,UAAU,UAAU;AAC9C,IAAM,aAAA,GAAgB,UAAU,MAAM;AACtC,IAAM,cAAA,GAAiB,UAAU,OAAO;AACxC,IAAM,eAAA,GAAkB,UAAU,QAAQ;AAC1C,IAAM,eAAA,GAAkB,UAAU,OAAO;AAMzC,IAAM,mBAAA,uBAA+C,GAAA,CAAI;AAAA,EAC9D,GAAG,aAAA;AAAA,EACH,GAAG;AACL,CAAC;AAGM,IAAM,uBAAA,uBAAmD,GAAA,CAAI;AAAA,EAClE,GAAG,iBAAA;AAAA,EACH,GAAG;AACL,CAAC;AAOM,SAAS,kBAAkB,OAAA,EAA0B;AAC1D,EAAA,OAAO,aAAA,CAAc,IAAI,OAAO,CAAA;AAClC;AAGO,SAAS,0BAA0B,OAAA,EAA0B;AAClE,EAAA,OACE,iBAAA,CAAkB,GAAA,CAAI,OAAO,CAAA,IAAK,cAAA,CAAe,IAAI,OAAO,CAAA,IAAK,aAAA,CAAc,GAAA,CAAI,OAAO,CAAA;AAE9F;AAmBO,IAAM,qBAAA,uBAAiD,GAAA,CAAI;AAAA,EAChE,GAAG,aAAA;AAAA,EACH,GAAG,aAAA;AAAA,EACH,GAAG;AACL,CAAC;AAKM,SAAS,iBAAiB,UAAA,EAG/B;AACA,EAAA,IAAI,CAAC,UAAA,EAAY,OAAO,EAAE,QAAQ,KAAA,EAAM;AACxC,EAAA,IAAI,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAG,QAAQ,IAAA,EAAK;AACpF,EAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,KAAA,EAAM;AAC3C","file":"chunk-NMT7BRLO.js","sourcesContent":["/**\n * The native-concept taxonomy, stated ONCE - with each call path's historical\n * view exported explicitly, because the three copies this consolidates had\n * DRIFTED and K1 preserved each path's observable behavior exactly (see\n * `concept-taxonomy-characterization.test.ts`).\n *\n * The sets below spell the codes MTHDS actually defines (the `native` domain of\n * the language spec). That is not pedantry: a set that named a concept the\n * language does not have is what broke `native.Number`, because the render path\n * knew the concept and the value path did not.\n *\n * The drift, recorded for M1 (where the server-derived descriptor retires this\n * module entirely):\n *\n * | concept | field mapper (render) | wire format (deflate/inflate) | value bridge (content wrapper) |\n * | ------- | ------------------------- | ----------------------------- | ------------------------------ |\n * | Text | text/prose | bare string | `{text}`, from `TextContent` |\n * | Number | number | `{concept, content}` | `{number}`, from `NumberContent` |\n * | YesNo | boolean | `{concept, content}` | `{yes_no}`, from `YesNoContent` |\n * | Date | text/prose (NOT a picker) | CUSTOM `{concept, content}` | `{text}` - WRONG, see below |\n * | Html | nested object | `{concept, content}` | - |\n * | Page | document | document-like (bare URL) | - |\n *\n * A `Date` input therefore ships as `{concept: \"native.Date\", content: {text}}`\n * today - consistent end-to-end, but not `DateContent {date, time}`. Changing\n * that is a wire-visible fix and belongs to M1, not here.\n *\n * `HTML_CONCEPTS` below spells the code `HTML`; the language spells it `Html`\n * (`NativeConceptCode.HTML = \"Html\"`), so the set matches nothing a real\n * contract carries and `native.Html` falls through to the generic object\n * dispatch - a nested card over `HtmlContent {inner_html, css_class}`, which\n * round-trips correctly. Correcting the spelling would route `native.Html` into\n * the prose-plus-`{text}` drift above and BREAK inputs that work today, so the\n * spelling is left alone deliberately and goes with the Date fix at M1.\n */\n\n/** Both spellings a concept ref uses: bare (`Text`) and namespaced (`native.Text`). */\nfunction nativeSet(...names: string[]): ReadonlySet<string> {\n return new Set(names.flatMap((n) => [n, `native.${n}`]));\n}\n\nexport const TEXT_CONCEPTS = nativeSet('Text');\nexport const DATE_CONCEPTS = nativeSet('Date');\n/** Deliberately the code the language does NOT use - see the header. */\nexport const HTML_CONCEPTS = nativeSet('HTML');\nexport const DOCUMENT_CONCEPTS = nativeSet('Document');\nexport const PAGE_CONCEPTS = nativeSet('Page');\nexport const IMAGE_CONCEPTS = nativeSet('Image');\nexport const NUMBER_CONCEPTS = nativeSet('Number');\nexport const YES_NO_CONCEPTS = nativeSet('YesNo');\n\n// ─── The field mapper's view (field-model.ts) ───────────────────────────────\n\n/** Concepts the mapper renders as text/prose - `Date` deliberately included\n * (a `native.Date` input renders as prose today, not as a date picker). */\nexport const FIELD_TEXT_CONCEPTS: ReadonlySet<string> = new Set([\n ...TEXT_CONCEPTS,\n ...DATE_CONCEPTS,\n]);\n\n/** Concepts the mapper renders as a document upload - `Page` folded in. */\nexport const FIELD_DOCUMENT_CONCEPTS: ReadonlySet<string> = new Set([\n ...DOCUMENT_CONCEPTS,\n ...PAGE_CONCEPTS,\n]);\n\n// ─── The wire format's view (input-format.ts) ───────────────────────────────\n\n/** True when the simplified wire form is a bare string (`{text} ↔ \"...\"`).\n * `Date` is NOT here: it travels through the custom-concept `{concept,\n * content}` branch (the drift the header records). */\nexport function isWireTextConcept(concept: string): boolean {\n return TEXT_CONCEPTS.has(concept);\n}\n\n/** True when the simplified wire form is a bare URL string. */\nexport function isWireDocumentLikeConcept(concept: string): boolean {\n return (\n DOCUMENT_CONCEPTS.has(concept) || IMAGE_CONCEPTS.has(concept) || PAGE_CONCEPTS.has(concept)\n );\n}\n\n// ─── The value bridge's view (run-values.ts) ────────────────────────────────\n\n/**\n * The FALLBACK text wrapper, for a text concept whose contract declares no\n * single-property content model to read the wrapper name off.\n *\n * The wrapper property is normally derived from the declared schema, in\n * `derive.ts`, and travels on the descriptor as `RunField.contentKey` - so the\n * value bridge wraps by name and holds no taxonomy of its own. This set is what\n * answers when that derivation finds nothing:\n *\n * - `native.Text` with a degenerate contract (a bare `{type: 'object'}`, or a\n * bare `{type: 'string'}`) still wraps as `{text}`, as it always has;\n * - `native.Date` declares `DateContent {date, time}` - two properties, so no\n * single wrapper - and this set is what keeps it wrapping as `{text}`. That\n * is the recorded drift, preserved on purpose until M1.\n */\nexport const TEXT_WRAPPER_CONCEPTS: ReadonlySet<string> = new Set([\n ...TEXT_CONCEPTS,\n ...DATE_CONCEPTS,\n ...HTML_CONCEPTS,\n]);\n\n// ─── List refs ──────────────────────────────────────────────────────────────\n\n/** A concept ref like `native.Document[]` → base `native.Document`, isList true. */\nexport function splitListConcept(conceptRef: string | undefined): {\n base?: string;\n isList: boolean;\n} {\n if (!conceptRef) return { isList: false };\n if (conceptRef.endsWith('[]')) return { base: conceptRef.slice(0, -2), isList: true };\n return { base: conceptRef, isList: false };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/schema-utils.ts"],"names":[],"mappings":"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","file":"chunk-O4O3QNVC.js","sourcesContent":["/**\n * The ONE place JSON-Schema plumbing lives for the run form kernel: nullable\n * `anyOf` collapsing, `$defs` collection/hoisting, `$ref` resolution, and type\n * extraction. Consolidated from three drifted private copies (`field-model.ts`,\n * `normalize-schema.ts`, `input-format.ts`) during the form-kernel extraction.\n *\n * Two collapse engines are exported ON PURPOSE - their semantics genuinely\n * differ, and each caller's observable behavior is characterized and preserved\n * (see `schema-utils-characterization.test.ts`):\n *\n * - `collapseNullable` (the field mapper's rule): collapse ONLY when exactly one\n * non-null branch remains, dropping the null. A multi-branch union stays an\n * `anyOf` and maps to the raw-JSON escape hatch.\n * - `flattenAnyOf` (the RJSF/ajv rule): a union of simple primitives becomes a\n * `type` ARRAY (null preserved as a type entry - ajv validates `type:\n * [\"number\",\"null\"]` natively); a 2-branch nullable non-primitive drops the\n * null branch.\n *\n * Whether these converge (and which semantics win) is an M1 question, decided\n * when the descriptor derivation moves server-side - not silently here.\n */\n\nexport type JsonSchema = Record<string, unknown>;\n\n// ─── anyOf collapsing ────────────────────────────────────────────────────────\n\n/** Pydantic emits `anyOf: [T, {type:'null'}]` for Optional[T]; collapse to T.\n * Collapses ONLY when exactly one non-null branch remains; the branch merges\n * OVER the outer schema (its constraints win). */\nexport function collapseNullable(schema: JsonSchema): JsonSchema {\n const anyOf = schema.anyOf;\n if (!Array.isArray(anyOf)) return schema;\n const branches = anyOf as JsonSchema[];\n const nonNull = branches.filter((b) => b?.type !== 'null');\n if (nonNull.length === 1) return { ...stripAnyOf(schema), ...nonNull[0] };\n return schema;\n}\n\nconst PRIMITIVE_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null']);\n\n/**\n * An `anyOf` entry that is a simple primitive with no constraints:\n * `{type: \"string\"}` is simple, `{type: \"string\", maxLength: 10}` is not.\n */\nfunction isSimplePrimitive(schema: JsonSchema): boolean {\n const type = schema.type;\n if (typeof type !== 'string' || !PRIMITIVE_TYPES.has(type)) return false;\n const allowedKeys = new Set(['type', 'default', 'description', 'title']);\n return Object.keys(schema).every((key) => allowedKeys.has(key));\n}\n\n/**\n * The RJSF/ajv collapse: a union of simple primitives flattens to a `type`\n * array (`anyOf: [{string},{null}]` → `type: [\"string\",\"null\"]`, which RJSF\n * renders as a plain input instead of a sub-schema picker); an exactly-two\n * `[T, {null}]` union of anything else drops the null branch and merges T over\n * the outer schema. Anything else passes through unchanged.\n */\nexport function flattenAnyOf(schema: JsonSchema): JsonSchema {\n const anyOf = schema.anyOf;\n if (!Array.isArray(anyOf)) return schema;\n\n const branches = anyOf as JsonSchema[];\n\n // Case 1: all branches are simple primitives → type array.\n if (\n branches.every(\n (branch) => typeof branch === 'object' && branch !== null && isSimplePrimitive(branch),\n )\n ) {\n const types: string[] = [];\n let mergedDefault: unknown = undefined;\n for (const branch of branches) {\n types.push(branch.type as string);\n if (branch.default !== undefined) mergedDefault = branch.default;\n }\n const { anyOf: _, ...rest } = schema;\n const result: JsonSchema = { ...rest, type: types };\n if (mergedDefault !== undefined && result.default === undefined) {\n result.default = mergedDefault;\n }\n return result;\n }\n\n // Case 2: exactly [T, {type: \"null\"}] - nullable non-primitive → drop null.\n if (branches.length === 2) {\n const nullBranch = branches.find(\n (b) => typeof b === 'object' && b !== null && b.type === 'null',\n );\n const otherBranch = branches.find((b) => b !== nullBranch);\n if (nullBranch && otherBranch && typeof otherBranch === 'object') {\n const { anyOf: _, ...rest } = schema;\n return { ...rest, ...otherBranch };\n }\n }\n\n return schema;\n}\n\nfunction stripAnyOf(schema: JsonSchema): JsonSchema {\n const { anyOf: _drop, ...rest } = schema;\n return rest;\n}\n\n// ─── Type & $ref helpers ─────────────────────────────────────────────────────\n\n/** The schema's non-null type: a bare `type` string, or the first non-null\n * entry of a `type` array (`[\"number\",\"null\"]` → `\"number\"`). */\nexport function schemaTypeOf(schema: JsonSchema): string | undefined {\n const t = schema.type;\n if (typeof t === 'string') return t;\n if (Array.isArray(t)) return t.find((x) => x !== 'null') as string | undefined;\n return undefined;\n}\n\n/** Resolve `{ $ref: \"#/$defs/Foo\" }` against a collected `$defs` map. Sibling\n * keys on the referencing schema override the definition's. */\nexport function derefSchema(schema: JsonSchema, defs: Record<string, JsonSchema>): JsonSchema {\n const ref = schema.$ref;\n if (typeof ref === 'string' && ref.startsWith('#/$defs/')) {\n const resolved = defs[ref.slice('#/$defs/'.length)];\n if (resolved) return { ...resolved, ...stripRef(schema) };\n }\n return schema;\n}\n\nfunction stripRef(schema: JsonSchema): JsonSchema {\n const { $ref: _drop, ...rest } = schema;\n return rest;\n}\n\n/**\n * Resolve the indirection layers pydantic puts in front of a value schema - a\n * `#/$defs/...` ref, a nullable `anyOf: [T, {null}]` wrapper, or a stack of\n * both - until a plain schema remains. This is the resolver `healStringWrappers`\n * and `pruneEmptyOptionals` apply before reading `type`. Unlike `derefSchema`\n * it REPLACES the schema with the definition (no sibling merge) - exactly what\n * the callers did inline.\n */\nexport function resolveSchemaIndirection(\n schema: JsonSchema,\n defs: Record<string, JsonSchema>,\n): JsonSchema {\n let current = schema;\n for (;;) {\n const ref = current.$ref;\n if (typeof ref === 'string' && ref.startsWith('#/$defs/')) {\n const resolved = defs[ref.slice('#/$defs/'.length)];\n if (resolved) {\n current = resolved;\n continue;\n }\n }\n if (Array.isArray(current.anyOf)) {\n const nonNull = (current.anyOf as JsonSchema[]).filter((b) => b?.type !== 'null');\n if (nonNull.length === 1) {\n current = nonNull[0]!;\n continue;\n }\n }\n return current;\n }\n}\n\n// ─── $defs collection ────────────────────────────────────────────────────────\n\nexport interface CollectDefsOptions {\n /**\n * Whether the walk descends into JSON arrays (`anyOf`/`allOf` branches,\n * tuple `items`). The field mapper always has (so a def declared inside an\n * `anyOf` branch resolves); the wire-format heal path historically has NOT -\n * both behaviors are characterized, and each caller states its mode\n * explicitly until M1 retires the difference.\n */\n traverseArrays: boolean;\n}\n\n/**\n * Collect every nested `$defs` entry into one flat map so `#/$defs/...` refs\n * resolve from anywhere. First definition of a name wins. The input schema is\n * NOT modified (see `hoistDefsToRoot` for the stripping variant).\n */\nexport function collectSchemaDefs(\n schema: JsonSchema,\n into: Record<string, JsonSchema>,\n options: CollectDefsOptions,\n): Record<string, JsonSchema> {\n for (const [key, value] of Object.entries(schema)) {\n if (key === '$defs' && value && typeof value === 'object' && !Array.isArray(value)) {\n for (const [name, def] of Object.entries(value as Record<string, JsonSchema>)) {\n if (!(name in into) && def && typeof def === 'object') {\n into[name] = def;\n collectSchemaDefs(def, into, options);\n }\n }\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\n collectSchemaDefs(value as JsonSchema, into, options);\n } else if (options.traverseArrays && Array.isArray(value)) {\n // Any object item recurses - including a nested array, whose indices then\n // walk as keys (matches the historical field-model walker exactly).\n for (const item of value) {\n if (item && typeof item === 'object') {\n collectSchemaDefs(item as JsonSchema, into, options);\n }\n }\n }\n }\n return into;\n}\n\n// ─── $defs hoisting (the RJSF wrapper-schema case) ──────────────────────────\n\n/**\n * Walk a schema, collect every `$defs` entry into `collected`, and return the\n * schema with those nested `$defs` STRIPPED. Cycle-safe: a def name is claimed\n * (placeholder) before its body is walked.\n */\nfunction walkAndCollectDefs(schema: JsonSchema, collected: JsonSchema): JsonSchema {\n const out: JsonSchema = {};\n for (const [key, value] of Object.entries(schema)) {\n if (key === '$defs' && value && typeof value === 'object' && !Array.isArray(value)) {\n for (const [defName, defValue] of Object.entries(value as JsonSchema)) {\n if (!(defName in collected) && defValue && typeof defValue === 'object') {\n collected[defName] = {};\n collected[defName] = walkAndCollectDefs(defValue as JsonSchema, collected);\n }\n }\n // Don't copy `$defs` into out - it's hoisted to the root.\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\n out[key] = walkAndCollectDefs(value as JsonSchema, collected);\n } else if (Array.isArray(value)) {\n out[key] = value.map((item) =>\n item && typeof item === 'object' && !Array.isArray(item)\n ? walkAndCollectDefs(item as JsonSchema, collected)\n : item,\n );\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * Hoist every nested `$defs` to the schema root, so a wrapper schema composed\n * from several pydantic sub-schemas keeps its `#/$defs/...` refs resolvable.\n * (Pydantic emits one `$defs` per model; composing models as properties of a\n * wrapper object leaves those maps below the root the refs point to.)\n */\nexport function hoistDefsToRoot(schema: JsonSchema): JsonSchema {\n const collected: JsonSchema = {};\n const stripped = walkAndCollectDefs(schema, collected);\n if (Object.keys(collected).length > 0) {\n stripped.$defs = collected;\n }\n return stripped;\n}\n"]}
@@ -1,132 +0,0 @@
1
- import { collectSchemaDefs, collapseNullable, derefSchema, schemaTypeOf } from './chunk-O4O3QNVC.js';
2
- import { isOptionalInput, inputMustBeFilled } from './chunk-HARYEWNG.js';
3
- import { splitListConcept, FIELD_DOCUMENT_CONCEPTS, IMAGE_CONCEPTS, FIELD_TEXT_CONCEPTS, HTML_CONCEPTS, TEXT_WRAPPER_CONCEPTS, NUMBER_CONCEPTS, YES_NO_CONCEPTS } from './chunk-NMT7BRLO.js';
4
-
5
- // src/core/derive.ts
6
- function isDocumentObject(schema) {
7
- const props = schema.properties;
8
- return Boolean(props?.url);
9
- }
10
- function scalarWrapper(schema, ctx) {
11
- const props = schema.properties;
12
- const entries = props ? Object.entries(props) : [];
13
- const only = entries.length === 1 ? entries[0] : void 0;
14
- if (!only) return void 0;
15
- const [key, propSchema] = only;
16
- return { key, schema: collapseNullable(derefSchema(propSchema ?? {}, ctx.defs)) };
17
- }
18
- function mapSchema(name, conceptRef, rawSchema, required, ctx) {
19
- const schema = collapseNullable(derefSchema(rawSchema, ctx.defs));
20
- const common = {
21
- name,
22
- conceptRef,
23
- description: typeof schema.description === "string" ? schema.description : void 0,
24
- required
25
- };
26
- const { base, isList } = splitListConcept(conceptRef);
27
- if (isList || schemaTypeOf(schema) === "array") {
28
- const itemsSchema = schema.items ?? {};
29
- const item = mapSchema(name, base, itemsSchema, true, { ...ctx, depth: ctx.depth + 1 });
30
- const itemCount = numOrUndef(schema.minItems);
31
- const maxItemCount = numOrUndef(schema.maxItems);
32
- return {
33
- ...common,
34
- kind: "list",
35
- item,
36
- ...itemCount === void 0 ? {} : { itemCount },
37
- ...maxItemCount === void 0 ? {} : { maxItemCount }
38
- };
39
- }
40
- if (Array.isArray(schema.enum)) {
41
- return { ...common, kind: "enum", options: schema.enum.map(String) };
42
- }
43
- if (base) {
44
- if (FIELD_DOCUMENT_CONCEPTS.has(base))
45
- return { ...common, kind: "document", accept: "PDF, DOCX, TXT" };
46
- if (IMAGE_CONCEPTS.has(base)) return { ...common, kind: "image", accept: "PNG, JPG, WEBP" };
47
- const wrapper = scalarWrapper(schema, ctx);
48
- if (FIELD_TEXT_CONCEPTS.has(base) || HTML_CONCEPTS.has(base)) {
49
- const contentKey = wrapper?.key ?? (TEXT_WRAPPER_CONCEPTS.has(base) ? "text" : void 0);
50
- return ctx.depth === 0 ? { ...common, contentKey, kind: "prose" } : { ...common, contentKey, kind: "text" };
51
- }
52
- if (NUMBER_CONCEPTS.has(base))
53
- return {
54
- ...common,
55
- contentKey: wrapper?.key,
56
- kind: "number",
57
- // `NumberContent.number` is `int | float`, an unresolvable union, so the
58
- // control stays a float input. Constraints are read off the WRAPPED
59
- // property - the wrapper object never carries them, which is why the
60
- // outer schema always answered `undefined`.
61
- integer: false,
62
- min: numOrUndef(wrapper?.schema.minimum ?? schema.minimum),
63
- max: numOrUndef(wrapper?.schema.maximum ?? schema.maximum)
64
- };
65
- if (YES_NO_CONCEPTS.has(base)) return { ...common, contentKey: wrapper?.key, kind: "boolean" };
66
- }
67
- if (isDocumentObject(schema)) {
68
- return { ...common, kind: "document", accept: "PDF, DOCX, TXT" };
69
- }
70
- const type = schemaTypeOf(schema);
71
- switch (type) {
72
- case "string": {
73
- if (base && (FIELD_DOCUMENT_CONCEPTS.has(base) || base === "native.Document"))
74
- return { ...common, kind: "document", accept: "PDF, DOCX, TXT" };
75
- if (schema.format === "date" || schema.format === "date-time")
76
- return { ...common, kind: "date", datetime: schema.format === "date-time" };
77
- const long = base && FIELD_TEXT_CONCEPTS.has(base) ? ctx.depth === 0 : typeof schema.maxLength === "number" ? schema.maxLength > 120 : false;
78
- return long ? { ...common, kind: "prose" } : { ...common, kind: "text", placeholder: void 0 };
79
- }
80
- case "integer":
81
- return {
82
- ...common,
83
- kind: "number",
84
- integer: true,
85
- min: numOrUndef(schema.minimum),
86
- max: numOrUndef(schema.maximum)
87
- };
88
- case "number":
89
- return {
90
- ...common,
91
- kind: "number",
92
- integer: false,
93
- min: numOrUndef(schema.minimum),
94
- max: numOrUndef(schema.maximum)
95
- };
96
- case "boolean":
97
- return { ...common, kind: "boolean" };
98
- case "object": {
99
- const props = schema.properties ?? {};
100
- const req = new Set(Array.isArray(schema.required) ? schema.required : []);
101
- const fields = Object.entries(props).map(
102
- ([fieldName, fieldSchema]) => mapSchema(fieldName, void 0, fieldSchema, req.has(fieldName), {
103
- ...ctx,
104
- depth: ctx.depth + 1
105
- })
106
- );
107
- return { ...common, kind: "object", fields };
108
- }
109
- default:
110
- if (base && FIELD_TEXT_CONCEPTS.has(base))
111
- return ctx.depth === 0 ? { ...common, kind: "prose" } : { ...common, kind: "text" };
112
- return { ...common, kind: "unknown" };
113
- }
114
- }
115
- function numOrUndef(v) {
116
- return typeof v === "number" ? v : void 0;
117
- }
118
- function buildRunFields(inputs) {
119
- return Object.entries(inputs).map(([name, input]) => {
120
- const defs = {};
121
- collectSchemaDefs(input.json_schema, defs, { traverseArrays: true });
122
- const field = mapSchema(name, input.concept_ref, input.json_schema, !isOptionalInput(input), {
123
- defs,
124
- depth: 0
125
- });
126
- return { ...field, gating: inputMustBeFilled(input) };
127
- });
128
- }
129
-
130
- export { buildRunFields };
131
- //# sourceMappingURL=chunk-VMLXO5JS.js.map
132
- //# sourceMappingURL=chunk-VMLXO5JS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/derive.ts"],"names":[],"mappings":"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","file":"chunk-VMLXO5JS.js","sourcesContent":["/**\n * The ONE derivation function: `PipeInputContract` map → `RunField[]`.\n *\n * Everything heuristic stays module-private behind `buildRunFields`: the\n * native-concept taxonomy, `isDocumentObject`, the depth-based prose/label\n * rule, the `accept` strings, list splitting. Nothing here is exported except\n * the function itself - so the M1 milestone can swap the source of the\n * descriptor (server-derived) without touching consumers.\n */\n\nimport { inputMustBeFilled, isOptionalInput, type PipeInputContract } from './contracts';\nimport type { RunField, RunFieldCommon } from './descriptor';\nimport {\n FIELD_DOCUMENT_CONCEPTS,\n FIELD_TEXT_CONCEPTS,\n HTML_CONCEPTS,\n IMAGE_CONCEPTS,\n NUMBER_CONCEPTS,\n splitListConcept,\n TEXT_WRAPPER_CONCEPTS,\n YES_NO_CONCEPTS,\n} from './native-concepts';\nimport {\n collapseNullable,\n collectSchemaDefs,\n derefSchema,\n schemaTypeOf,\n type JsonSchema,\n} from './schema-utils';\n\n// Native concepts arrive as their pydantic wrapper schema (e.g. native.Text is\n// `TextContent {text}`, native.Document is `DocumentContent {url,…}`), NOT a bare\n// primitive - so we map them by concept_ref, before the generic schema-type\n// dispatch, or they'd all render as nested objects. The taxonomy lives in\n// `native-concepts.ts`, which also records where this mapper's view drifts from\n// the wire format's.\n\n/**\n * A url-bearing object renders as a document field. This is `Boolean(\n * schema.properties?.url)` and nothing more: the historical description check\n * (\"storage url\" / \"document url\") was followed by `|| 'url' in props`, which\n * made it unreachable. Stated honestly as the heuristic it is - M1 replaces it\n * with the server-derived descriptor; narrowing it to the description match is\n * a recorded M1 option, not a K1 change.\n */\nfunction isDocumentObject(schema: JsonSchema): boolean {\n const props = schema.properties as Record<string, JsonSchema> | undefined;\n return Boolean(props?.url);\n}\n\ninterface MapCtx {\n defs: Record<string, JsonSchema>;\n depth: number;\n}\n\n/**\n * The single property a pydantic scalar content model holds its value in -\n * `TextContent {text}`, `NumberContent {number}`, `YesNoContent {yes_no}`.\n *\n * A native scalar's value does NOT sit at the top of its declared schema, and\n * this is where that is discovered: from the CONTRACT, not from a hand-kept\n * list of which concepts wrap. Keeping such a list is what broke `native.Number`\n * - the render taxonomy knew the concept, the wrapper taxonomy did not, so a\n * number reached the gate bare and failed against `NumberContent`. Reading the\n * declared shape covers a concept nobody remembered to add.\n *\n * A wrapper is a schema declaring EXACTLY ONE property. A multi-property content\n * model (`DateContent {date, time}`, `HtmlContent {inner_html, css_class}`) is\n * not one and deliberately answers `undefined`; so does a contract that declares\n * no properties at all. The returned `schema` is the WRAPPED property's, which\n * is where its constraints live.\n */\nfunction scalarWrapper(\n schema: JsonSchema,\n ctx: MapCtx,\n): { key: string; schema: JsonSchema } | undefined {\n const props = schema.properties as Record<string, JsonSchema> | undefined;\n const entries = props ? Object.entries(props) : [];\n const only = entries.length === 1 ? entries[0] : undefined;\n if (!only) return undefined;\n const [key, propSchema] = only;\n return { key, schema: collapseNullable(derefSchema(propSchema ?? {}, ctx.defs)) };\n}\n\n/** Build the recursive RunField for a single resolved schema node. */\nfunction mapSchema(\n name: string,\n conceptRef: string | undefined,\n rawSchema: JsonSchema,\n required: boolean,\n ctx: MapCtx,\n): RunField {\n const schema = collapseNullable(derefSchema(rawSchema, ctx.defs));\n // The LABEL is always the stuff name (the variable key) - that's what\n // identifies the input in the method. We deliberately do NOT use\n // `schema.title`, which is the pydantic model name (TextContent, ImageContent,\n // DocumentContent…) and would mask the stuff name. The concept pill carries\n // the type instead. `title` stays undefined here so FieldShell falls back to\n // `name`; list items still pass `title: ''` to suppress the per-row label.\n const common: RunFieldCommon = {\n name,\n conceptRef,\n description: typeof schema.description === 'string' ? schema.description : undefined,\n required,\n };\n\n const { base, isList } = splitListConcept(conceptRef);\n\n // List concepts (native.Text[], demo.Invoice[]) and array schemas.\n if (isList || schemaTypeOf(schema) === 'array') {\n const itemsSchema = (schema.items as JsonSchema) ?? {};\n const item = mapSchema(name, base, itemsSchema, true, { ...ctx, depth: ctx.depth + 1 });\n // A declared count (`Concept[N]`) reaches the descriptor from the schema\n // keywords ajv itself reads - see `ListRunField.itemCount`. BOTH bounds\n // travel, because they are two facts: a `[N]` slot states them equal, but\n // this mapper also walks nested arrays, whose model may have stated only\n // one. Carrying a single number forced readiness and the control to read it\n // as a minimum and a maximum respectively.\n const itemCount = numOrUndef(schema.minItems);\n const maxItemCount = numOrUndef(schema.maxItems);\n return {\n ...common,\n kind: 'list',\n item,\n ...(itemCount === undefined ? {} : { itemCount }),\n ...(maxItemCount === undefined ? {} : { maxItemCount }),\n };\n }\n\n // Enum (a custom concept may refine a native with a fixed value set).\n if (Array.isArray(schema.enum)) {\n return { ...common, kind: 'enum', options: schema.enum.map(String) };\n }\n\n // Native concepts: map by concept_ref regardless of the wrapper schema shape.\n if (base) {\n if (FIELD_DOCUMENT_CONCEPTS.has(base))\n return { ...common, kind: 'document', accept: 'PDF, DOCX, TXT' };\n if (IMAGE_CONCEPTS.has(base)) return { ...common, kind: 'image', accept: 'PNG, JPG, WEBP' };\n\n // The three native scalars render as a bare control but travel inside the\n // content model their concept declares. `contentKey` carries that property\n // name to the value bridge, which is how the control can hold `2` while the\n // wire carries `{number: 2}`.\n const wrapper = scalarWrapper(schema, ctx);\n\n if (FIELD_TEXT_CONCEPTS.has(base) || HTML_CONCEPTS.has(base)) {\n // `Date` declares two properties, so no wrapper is found for it and the\n // `{text}` fallback answers instead - the recorded drift, kept until the\n // derivation swap (see `native-concepts.ts`).\n const contentKey = wrapper?.key ?? (TEXT_WRAPPER_CONCEPTS.has(base) ? 'text' : undefined);\n return ctx.depth === 0\n ? { ...common, contentKey, kind: 'prose' }\n : { ...common, contentKey, kind: 'text' };\n }\n if (NUMBER_CONCEPTS.has(base))\n return {\n ...common,\n contentKey: wrapper?.key,\n kind: 'number',\n // `NumberContent.number` is `int | float`, an unresolvable union, so the\n // control stays a float input. Constraints are read off the WRAPPED\n // property - the wrapper object never carries them, which is why the\n // outer schema always answered `undefined`.\n integer: false,\n min: numOrUndef(wrapper?.schema.minimum ?? schema.minimum),\n max: numOrUndef(wrapper?.schema.maximum ?? schema.maximum),\n };\n if (YES_NO_CONCEPTS.has(base)) return { ...common, contentKey: wrapper?.key, kind: 'boolean' };\n }\n\n // A custom concept whose schema looks like DocumentContent (refines Document).\n if (isDocumentObject(schema)) {\n return { ...common, kind: 'document', accept: 'PDF, DOCX, TXT' };\n }\n\n const type = schemaTypeOf(schema);\n switch (type) {\n case 'string': {\n if (base && (FIELD_DOCUMENT_CONCEPTS.has(base) || base === 'native.Document'))\n return { ...common, kind: 'document', accept: 'PDF, DOCX, TXT' };\n // A `date` structure field compiles to a `format: date`/`date-time`\n // string. Render it as a real date picker so the user picks a day - no\n // hand-typed timestamps - and stores a value the API accepts.\n if (schema.format === 'date' || schema.format === 'date-time')\n return { ...common, kind: 'date', datetime: schema.format === 'date-time' };\n // A top-level Text input is usually the main prompt (roomy textarea); the\n // same concept nested in a concept/list is usually a short attribute\n // (name, label) and reads better as a single line.\n const long =\n base && FIELD_TEXT_CONCEPTS.has(base)\n ? ctx.depth === 0\n : typeof schema.maxLength === 'number'\n ? schema.maxLength > 120\n : false;\n return long\n ? { ...common, kind: 'prose' }\n : { ...common, kind: 'text', placeholder: undefined };\n }\n case 'integer':\n return {\n ...common,\n kind: 'number',\n integer: true,\n min: numOrUndef(schema.minimum),\n max: numOrUndef(schema.maximum),\n };\n case 'number':\n return {\n ...common,\n kind: 'number',\n integer: false,\n min: numOrUndef(schema.minimum),\n max: numOrUndef(schema.maximum),\n };\n case 'boolean':\n return { ...common, kind: 'boolean' };\n case 'object': {\n const props = (schema.properties as Record<string, JsonSchema>) ?? {};\n const req = new Set(Array.isArray(schema.required) ? (schema.required as string[]) : []);\n const fields = Object.entries(props).map(([fieldName, fieldSchema]) =>\n mapSchema(fieldName, undefined, fieldSchema, req.has(fieldName), {\n ...ctx,\n depth: ctx.depth + 1,\n }),\n );\n return { ...common, kind: 'object', fields };\n }\n default:\n // A bare `native.Text` concept may arrive as `{type:'string'}` (handled\n // above) but a custom concept with no resolvable shape lands here.\n if (base && FIELD_TEXT_CONCEPTS.has(base))\n return ctx.depth === 0 ? { ...common, kind: 'prose' } : { ...common, kind: 'text' };\n return { ...common, kind: 'unknown' };\n }\n}\n\nfunction numOrUndef(v: unknown): number | undefined {\n return typeof v === 'number' ? v : undefined;\n}\n\n/**\n * Convert the API's per-input contracts into the runner's field descriptors.\n * The map's insertion order is preserved (required-first is the caller's job).\n */\nexport function buildRunFields(inputs: Record<string, PipeInputContract>): RunField[] {\n return Object.entries(inputs).map(([name, input]) => {\n const defs: Record<string, JsonSchema> = {};\n collectSchemaDefs(input.json_schema, defs, { traverseArrays: true });\n // A top-level input is required unless the method declared it optional (`?`).\n const field = mapSchema(name, input.concept_ref, input.json_schema, !isOptionalInput(input), {\n defs,\n depth: 0,\n });\n // Whether Run gates on it is a SEPARATE question, and it is answered by the\n // contract, not by the shape we mapped it to - see `mustBeFilled`.\n return { ...field, gating: inputMustBeFilled(input) };\n });\n}\n"]}