@gleanwork/mcp-server-tester 1.1.1 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/dist/cli/index.js +16274 -2747
- package/dist/fixtures/mcp.d.ts +77 -59
- package/dist/fixtures/mcp.js +162 -28
- package/dist/fixtures/mcp.js.map +1 -1
- package/dist/{index-BlqLvjnP.d.cts → index-CwFHKIoN.d.cts} +3961 -2841
- package/dist/{index-BlqLvjnP.d.ts → index-CwFHKIoN.d.ts} +3961 -2841
- package/dist/index.cjs +11787 -3884
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +176 -5
- package/dist/index.d.ts +176 -5
- package/dist/index.js +11729 -3871
- package/dist/index.js.map +1 -1
- package/dist/reporters/mcpReporter.cjs +1 -0
- package/dist/reporters/mcpReporter.cjs.map +1 -1
- package/dist/reporters/mcpReporter.d.cts +83 -65
- package/dist/reporters/mcpReporter.d.ts +83 -65
- package/dist/reporters/mcpReporter.js +1 -0
- package/dist/reporters/mcpReporter.js.map +1 -1
- package/dist/reporters/ui-dist/app.js +18 -17
- package/dist/reporters/ui-dist/styles.css +1 -1
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/package.json +14 -3
- package/scripts/cowork-requirements.txt +5 -0
- package/scripts/cowork_computer_use.py +409 -0
|
@@ -1 +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: }/*! 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}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:221.2 83.2% 53.3%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:221.2 83.2% 53.3%;--radius:0.5rem}.dark{--background:222.2 84% 4.9%;--foreground:210 40% 98%;--card:222.2 84% 4.9%;--card-foreground:210 40% 98%;--popover:222.2 84% 4.9%;--popover-foreground:210 40% 98%;--primary:217.2 91.2% 59.8%;--primary-foreground:222.2 47.4% 11.2%;--secondary:217.2 32.6% 17.5%;--secondary-foreground:210 40% 98%;--muted:217.2 32.6% 17.5%;--muted-foreground:215 20.2% 65.1%;--accent:217.2 32.6% 17.5%;--accent-foreground:210 40% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;--border:217.2 32.6% 17.5%;--input:217.2 32.6% 17.5%;--ring:224.3 76.3% 48%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-feature-settings:"rlig" 1,"calt" 1}.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}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.sticky{position:sticky}.inset-0{inset:0}.top-0{top:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.h-1\.5{height:.375rem}.h-16{height:4rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-full{height:100%}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[250px\]{min-width:250px}.max-w-4xl{max-width:56rem}.max-w-\[1600px\]{max-width:1600px}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,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}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.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-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-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*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))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-4{border-left-width:4px}.border-amber-500\/20{border-color:rgba(245,158,11,.2)}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-blue-500\/20{border-color:rgba(59,130,246,.2)}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border)/.5)}.border-green-500{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity,1))}.border-green-500\/20{border-color:rgba(34,197,94,.2)}.border-muted-foreground\/40{border-color:hsl(var(--muted-foreground)/.4)}.border-primary{border-color:hsl(var(--primary))}.border-purple-500{--tw-border-opacity:1;border-color:rgb(168 85 247/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-red-500\/20{border-color:rgba(239,68,68,.2)}.border-transparent{border-color:transparent}.border-l-blue-500{--tw-border-opacity:1;border-left-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-l-blue-500\/30{border-left-color:rgba(59,130,246,.3)}.border-l-purple-500{--tw-border-opacity:1;border-left-color:rgb(168 85 247/var(--tw-border-opacity,1))}.border-l-purple-500\/30{border-left-color:rgba(168,85,247,.3)}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-amber-500\/10{background-color:rgba(245,158,11,.1)}.bg-amber-500\/15{background-color:rgba(245,158,11,.15)}.bg-amber-500\/20{background-color:rgba(245,158,11,.2)}.bg-background{background-color:hsl(var(--background))}.bg-black\/60{background-color:rgba(0,0,0,.6)}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-blue-500\/10{background-color:rgba(59,130,246,.1)}.bg-blue-500\/5{background-color:rgba(59,130,246,.05)}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-cyan-100{--tw-bg-opacity:1;background-color:rgb(207 250 254/var(--tw-bg-opacity,1))}.bg-destructive\/10{background-color:hsl(var(--destructive)/.1)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(240 253 244/var(--tw-bg-opacity,1))}.bg-green-500\/10{background-color:rgba(34,197,94,.1)}.bg-green-500\/15{background-color:rgba(34,197,94,.15)}.bg-green-500\/20{background-color:rgba(34,197,94,.2)}.bg-indigo-100{--tw-bg-opacity:1;background-color:rgb(224 231 255/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/10{background-color:hsl(var(--muted)/.1)}.bg-muted\/30{background-color:hsl(var(--muted)/.3)}.bg-muted\/50{background-color:hsl(var(--muted)/.5)}.bg-orange-500\/20{background-color:rgba(249,115,22,.2)}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary)/.1)}.bg-purple-100{--tw-bg-opacity:1;background-color:rgb(243 232 255/var(--tw-bg-opacity,1))}.bg-purple-500\/5{background-color:rgba(168,85,247,.05)}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-red-500\/10{background-color:rgba(239,68,68,.1)}.bg-red-500\/15{background-color:rgba(239,68,68,.15)}.bg-red-500\/20{background-color:rgba(239,68,68,.2)}.bg-secondary{background-color:hsl(var(--secondary))}.bg-slate-500\/20{background-color:rgba(100,116,139,.2)}.bg-transparent{background-color:transparent}.bg-violet-100{--tw-bg-opacity:1;background-color:rgb(237 233 254/var(--tw-bg-opacity,1))}.bg-yellow-50{--tw-bg-opacity:1;background-color:rgb(254 252 232/var(--tw-bg-opacity,1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.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-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.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-3{padding-top:.75rem;padding-bottom:.75rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.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-relaxed{line-height:1.625}.tracking-wide{letter-spacing:.025em}.text-amber-600{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity,1))}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-cyan-700{--tw-text-opacity:1;color:rgb(14 116 144/var(--tw-text-opacity,1))}.text-destructive{color:hsl(var(--destructive))}.text-foreground{color:hsl(var(--foreground))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity,1))}.text-indigo-700{--tw-text-opacity:1;color:rgb(67 56 202/var(--tw-text-opacity,1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-orange-600{--tw-text-opacity:1;color:rgb(234 88 12/var(--tw-text-opacity,1))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity,1))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-purple-600{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-purple-700{--tw-text-opacity:1;color:rgb(126 34 206/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-violet-700{--tw-text-opacity:1;color:rgb(109 40 217/var(--tw-text-opacity,1))}.text-yellow-600{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-sm,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.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)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.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}.scrollbar-thin::-webkit-scrollbar{width:8px;height:8px}.scrollbar-thin::-webkit-scrollbar-track{background-color:hsl(var(--secondary))}.scrollbar-thin::-webkit-scrollbar-thumb{border-radius:.25rem;background-color:hsl(var(--muted-foreground)/.2)}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:hsl(var(--muted-foreground)/.3)}@media (prefers-reduced-motion:reduce){*,:after,:before{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.last\:border-0:last-child{border-width:0}.hover\:border-border:hover{border-color:hsl(var(--border))}.hover\:border-muted:hover{border-color:hsl(var(--muted))}.hover\:border-primary:hover{border-color:hsl(var(--primary))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/50:hover{background-color:hsl(var(--accent)/.5)}.hover\:bg-blue-500\/15:hover{background-color:rgba(59,130,246,.15)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/20:hover{background-color:hsl(var(--muted)/.2)}.hover\:bg-muted\/30:hover{background-color:hsl(var(--muted)/.3)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary)/.8)}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--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\:ring-ring:focus{--tw-ring-color:hsl(var(--ring))}.group:hover .group-hover\:text-foreground{color:hsl(var(--foreground))}.dark\:border-red-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(153 27 27/var(--tw-border-opacity,1))}.dark\:bg-amber-900\/30:is(.dark *){background-color:rgba(120,53,15,.3)}.dark\:bg-blue-900\/30:is(.dark *){background-color:rgba(30,58,138,.3)}.dark\:bg-cyan-900\/30:is(.dark *){background-color:rgba(22,78,99,.3)}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-green-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(5 46 22/var(--tw-bg-opacity,1))}.dark\:bg-indigo-900\/30:is(.dark *){background-color:rgba(49,46,129,.3)}.dark\:bg-purple-900\/30:is(.dark *){background-color:rgba(88,28,135,.3)}.dark\:bg-red-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(69 10 10/var(--tw-bg-opacity,1))}.dark\:bg-red-950\/30:is(.dark *){background-color:rgba(69,10,10,.3)}.dark\:bg-violet-900\/30:is(.dark *){background-color:rgba(76,29,149,.3)}.dark\:bg-yellow-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(66 32 6/var(--tw-bg-opacity,1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity:1;color:rgb(252 211 77/var(--tw-text-opacity,1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 191 36/var(--tw-text-opacity,1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity,1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.dark\:text-cyan-300:is(.dark *){--tw-text-opacity:1;color:rgb(103 232 249/var(--tw-text-opacity,1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.dark\:text-indigo-300:is(.dark *){--tw-text-opacity:1;color:rgb(165 180 252/var(--tw-text-opacity,1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.dark\:text-purple-300:is(.dark *){--tw-text-opacity:1;color:rgb(216 180 254/var(--tw-text-opacity,1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.dark\:text-red-500:is(.dark *){--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.dark\:text-violet-300:is(.dark *){--tw-text-opacity:1;color:rgb(196 181 253/var(--tw-text-opacity,1))}@media (min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
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: }/*! 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}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:221.2 83.2% 53.3%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:221.2 83.2% 53.3%;--radius:0.5rem}.dark{--background:222.2 84% 4.9%;--foreground:210 40% 98%;--card:222.2 84% 4.9%;--card-foreground:210 40% 98%;--popover:222.2 84% 4.9%;--popover-foreground:210 40% 98%;--primary:217.2 91.2% 59.8%;--primary-foreground:222.2 47.4% 11.2%;--secondary:217.2 32.6% 17.5%;--secondary-foreground:210 40% 98%;--muted:217.2 32.6% 17.5%;--muted-foreground:215 20.2% 65.1%;--accent:217.2 32.6% 17.5%;--accent-foreground:210 40% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;--border:217.2 32.6% 17.5%;--input:217.2 32.6% 17.5%;--ring:224.3 76.3% 48%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-feature-settings:"rlig" 1,"calt" 1}.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}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.sticky{position:sticky}.inset-0{inset:0}.top-0{top:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.h-1\.5{height:.375rem}.h-16{height:4rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-full{height:100%}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[250px\]{min-width:250px}.max-w-4xl{max-width:56rem}.max-w-56{max-width:14rem}.max-w-\[1600px\]{max-width:1600px}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,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}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.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-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))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*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))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-amber-500\/20{border-color:rgba(245,158,11,.2)}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-blue-500\/20{border-color:rgba(59,130,246,.2)}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border)/.5)}.border-green-500{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity,1))}.border-green-500\/20{border-color:rgba(34,197,94,.2)}.border-green-500\/30{border-color:rgba(34,197,94,.3)}.border-muted-foreground\/40{border-color:hsl(var(--muted-foreground)/.4)}.border-orange-500\/30{border-color:rgba(249,115,22,.3)}.border-primary{border-color:hsl(var(--primary))}.border-purple-500{--tw-border-opacity:1;border-color:rgb(168 85 247/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-red-500\/20{border-color:rgba(239,68,68,.2)}.border-red-500\/30{border-color:rgba(239,68,68,.3)}.border-transparent{border-color:transparent}.border-l-blue-500{--tw-border-opacity:1;border-left-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-l-blue-500\/30{border-left-color:rgba(59,130,246,.3)}.border-l-purple-500{--tw-border-opacity:1;border-left-color:rgb(168 85 247/var(--tw-border-opacity,1))}.border-l-purple-500\/30{border-left-color:rgba(168,85,247,.3)}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-amber-500\/10{background-color:rgba(245,158,11,.1)}.bg-amber-500\/15{background-color:rgba(245,158,11,.15)}.bg-amber-500\/20{background-color:rgba(245,158,11,.2)}.bg-background{background-color:hsl(var(--background))}.bg-black\/60{background-color:rgba(0,0,0,.6)}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-blue-500\/10{background-color:rgba(59,130,246,.1)}.bg-blue-500\/5{background-color:rgba(59,130,246,.05)}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-cyan-100{--tw-bg-opacity:1;background-color:rgb(207 250 254/var(--tw-bg-opacity,1))}.bg-cyan-500\/15{background-color:rgba(6,182,212,.15)}.bg-destructive\/10{background-color:hsl(var(--destructive)/.1)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-500\/15{background-color:hsla(220,9%,46%,.15)}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(240 253 244/var(--tw-bg-opacity,1))}.bg-green-500\/10{background-color:rgba(34,197,94,.1)}.bg-green-500\/15{background-color:rgba(34,197,94,.15)}.bg-green-500\/20{background-color:rgba(34,197,94,.2)}.bg-indigo-100{--tw-bg-opacity:1;background-color:rgb(224 231 255/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/10{background-color:hsl(var(--muted)/.1)}.bg-muted\/30{background-color:hsl(var(--muted)/.3)}.bg-muted\/50{background-color:hsl(var(--muted)/.5)}.bg-orange-500\/10{background-color:rgba(249,115,22,.1)}.bg-orange-500\/20{background-color:rgba(249,115,22,.2)}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary)/.1)}.bg-purple-100{--tw-bg-opacity:1;background-color:rgb(243 232 255/var(--tw-bg-opacity,1))}.bg-purple-500\/5{background-color:rgba(168,85,247,.05)}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-red-500\/10{background-color:rgba(239,68,68,.1)}.bg-red-500\/15{background-color:rgba(239,68,68,.15)}.bg-red-500\/20{background-color:rgba(239,68,68,.2)}.bg-secondary{background-color:hsl(var(--secondary))}.bg-slate-500\/20{background-color:rgba(100,116,139,.2)}.bg-teal-100{--tw-bg-opacity:1;background-color:rgb(204 251 241/var(--tw-bg-opacity,1))}.bg-teal-500\/15{background-color:rgba(20,184,166,.15)}.bg-transparent{background-color:transparent}.bg-violet-100{--tw-bg-opacity:1;background-color:rgb(237 233 254/var(--tw-bg-opacity,1))}.bg-yellow-50{--tw-bg-opacity:1;background-color:rgb(254 252 232/var(--tw-bg-opacity,1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.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-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.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-3{padding-top:.75rem;padding-bottom:.75rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.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-relaxed{line-height:1.625}.tracking-wide{letter-spacing:.025em}.text-amber-600{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity,1))}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-cyan-700{--tw-text-opacity:1;color:rgb(14 116 144/var(--tw-text-opacity,1))}.text-destructive{color:hsl(var(--destructive))}.text-foreground{color:hsl(var(--foreground))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity,1))}.text-indigo-700{--tw-text-opacity:1;color:rgb(67 56 202/var(--tw-text-opacity,1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-orange-600{--tw-text-opacity:1;color:rgb(234 88 12/var(--tw-text-opacity,1))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity,1))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-purple-600{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-purple-700{--tw-text-opacity:1;color:rgb(126 34 206/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-teal-700{--tw-text-opacity:1;color:rgb(15 118 110/var(--tw-text-opacity,1))}.text-violet-700{--tw-text-opacity:1;color:rgb(109 40 217/var(--tw-text-opacity,1))}.text-yellow-600{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-sm,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.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)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.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}.scrollbar-thin::-webkit-scrollbar{width:8px;height:8px}.scrollbar-thin::-webkit-scrollbar-track{background-color:hsl(var(--secondary))}.scrollbar-thin::-webkit-scrollbar-thumb{border-radius:.25rem;background-color:hsl(var(--muted-foreground)/.2)}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:hsl(var(--muted-foreground)/.3)}@media (prefers-reduced-motion:reduce){*,:after,:before{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.last\:border-0:last-child{border-width:0}.hover\:border-border:hover{border-color:hsl(var(--border))}.hover\:border-muted:hover{border-color:hsl(var(--muted))}.hover\:border-primary:hover{border-color:hsl(var(--primary))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/50:hover{background-color:hsl(var(--accent)/.5)}.hover\:bg-blue-500\/15:hover{background-color:rgba(59,130,246,.15)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/20:hover{background-color:hsl(var(--muted)/.2)}.hover\:bg-muted\/30:hover{background-color:hsl(var(--muted)/.3)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary)/.8)}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--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\:ring-ring:focus{--tw-ring-color:hsl(var(--ring))}.group:hover .group-hover\:text-foreground{color:hsl(var(--foreground))}.dark\:border-red-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(153 27 27/var(--tw-border-opacity,1))}.dark\:bg-amber-900\/30:is(.dark *){background-color:rgba(120,53,15,.3)}.dark\:bg-blue-900\/30:is(.dark *){background-color:rgba(30,58,138,.3)}.dark\:bg-cyan-900\/30:is(.dark *){background-color:rgba(22,78,99,.3)}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-green-900\/30:is(.dark *){background-color:rgba(20,83,45,.3)}.dark\:bg-green-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(5 46 22/var(--tw-bg-opacity,1))}.dark\:bg-indigo-900\/30:is(.dark *){background-color:rgba(49,46,129,.3)}.dark\:bg-purple-900\/30:is(.dark *){background-color:rgba(88,28,135,.3)}.dark\:bg-red-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(69 10 10/var(--tw-bg-opacity,1))}.dark\:bg-red-950\/30:is(.dark *){background-color:rgba(69,10,10,.3)}.dark\:bg-teal-900\/30:is(.dark *){background-color:rgba(19,78,74,.3)}.dark\:bg-violet-900\/30:is(.dark *){background-color:rgba(76,29,149,.3)}.dark\:bg-yellow-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(66 32 6/var(--tw-bg-opacity,1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity:1;color:rgb(252 211 77/var(--tw-text-opacity,1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 191 36/var(--tw-text-opacity,1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity,1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.dark\:text-cyan-300:is(.dark *){--tw-text-opacity:1;color:rgb(103 232 249/var(--tw-text-opacity,1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity:1;color:rgb(134 239 172/var(--tw-text-opacity,1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.dark\:text-indigo-300:is(.dark *){--tw-text-opacity:1;color:rgb(165 180 252/var(--tw-text-opacity,1))}.dark\:text-orange-300:is(.dark *){--tw-text-opacity:1;color:rgb(253 186 116/var(--tw-text-opacity,1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.dark\:text-purple-300:is(.dark *){--tw-text-opacity:1;color:rgb(216 180 254/var(--tw-text-opacity,1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.dark\:text-red-500:is(.dark *){--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.dark\:text-teal-300:is(.dark *){--tw-text-opacity:1;color:rgb(94 234 212/var(--tw-text-opacity,1))}.dark\:text-violet-300:is(.dark *){--tw-text-opacity:1;color:rgb(196 181 253/var(--tw-text-opacity,1))}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
package/dist/types/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { A as AuthType,
|
|
1
|
+
export { A as AuthType, K as BuiltInRubric, N as BuiltInSanitizer, Q as CLIConfig, W as CLIOAuthClientConfig, X as CLIOAuthResult, Y as CLIOutputFormat, Z as CaseComparisonResult, _ as ClientCredentialsConfig, $ as CompareEvalRunsOptions, a0 as ComparisonOutcome, a1 as ContentBlock, a2 as CreateMCPClientOptions, a3 as CustomJudgeExecutor, a4 as CustomJudgeResult, a9 as EvalCase, aa as EvalCaseComparison, ab as EvalCaseComparisonOutcome, ac as EvalCaseRequest, l as EvalCaseResult, ae as EvalContext, o as EvalDataset, ag as EvalExpectBlock, ah as EvalExpectationResult, ak as EvalMode, ao as EvalRunComparisonLabels, ap as EvalRunComparisonResult, aq as EvalRunMetadata, ar as EvalRunnerOptions, r as EvalRunnerResult, ay as ExpectationBreakdown, az as ExpectationResultMap, aA as ExpectationType, aB as ExperimentMetric, aJ as FieldRemovalSanitizer, aT as HostDiagnostics, a_ as HostType, a$ as HttpMCPConfig, b0 as IterationResult, G as Judge, F as JudgeConfig, b1 as JudgeExpectConfig, J as JudgeMatcherOptions, b2 as JudgeResult, b3 as JudgeValidatorConfig, L as LLMProvider, b4 as LLMToolCall, b6 as LoadDatasetOptions, b7 as MCPAuthConfig, b8 as MCPAuthFixtures, b9 as MCPClientCredentialsConfig, p as MCPConfig, bb as MCPConformanceCheck, bc as MCPConformanceOptions, bd as MCPConformanceRaw, be as MCPConformanceResult, bf as MCPConformanceResultData, bg as MCPEvalData, bh as MCPEvalHistoricalSummary, bi as MCPEvalReporterConfig, bj as MCPEvalRunData, M as MCPFixtureApi, bk as MCPFixtureOptions, bl as MCPHostCapabilities, a as MCPHostConfig, b as MCPHostSimulationResult, bm as MCPHostSimulator, bn as MCPOAuthConfig, bo as MCPServerCapabilitiesData, br as NormalizedToolResponse, O as OAuthSetupConfig, P as PatternValidatorOptions, bu as PlaywrightOAuthClientProviderConfig, bv as PredicateResult, bw as ProposeVariantsContext, bx as ProtectedResourceDiscoveryResult, by as ProtectedResourceMetadata, bz as ProviderKind, bA as RegexSanitizer, bB as ResultSource, R as RubricSpec, bE as SaveBaselineOptions, bF as SaveEvalRunComparisonOptions, bG as SaveServerComparisonOptions, bH as SchemaRegistry, S as SchemaValidatorOptions, bI as SerializedEvalDataset, bJ as ServerComparisonOptions, bK as ServerComparisonResult, c as SizeValidatorOptions, d as SnapshotSanitizer, bL as SnapshotSanitizers, bM as StdioMCPConfig, bP as StoredClientInfo, bS as StoredEvalResultLoadOptions, bT as StoredEvalResultRef, bU as StoredEvalResultSaveOptions, bV as StoredEvalRunRef, bW as StoredOAuthState, bX as StoredServerMetadata, bY as StoredTokens, T as TextValidatorOptions, b_ as TokenResult, g as ToolCallCountOptions, f as ToolCallExpectation, b$ as ToolMetadataOverride, c0 as ToolOverrideVariant, e as ToolPredicate, c2 as UsageMetrics, V as ValidationResult, c3 as VariantCandidateResult, c4 as VariantExperimentOptions, c5 as VariantExperimentReason, c6 as VariantExperimentResult, c7 as VariantExperimentRound, c8 as VariantImprovementProposal, c9 as VariantRecommendation } from '../index-CwFHKIoN.cjs';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import '@playwright/test';
|
|
4
|
+
import '@modelcontextprotocol/sdk/client/index.js';
|
|
5
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
4
6
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
5
7
|
import '@modelcontextprotocol/sdk/shared/auth.js';
|
|
6
8
|
import 'oauth4webapi';
|
|
7
|
-
import '@modelcontextprotocol/sdk/client/index.js';
|
|
8
|
-
import '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import 'playwright/test';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { A as AuthType,
|
|
1
|
+
export { A as AuthType, K as BuiltInRubric, N as BuiltInSanitizer, Q as CLIConfig, W as CLIOAuthClientConfig, X as CLIOAuthResult, Y as CLIOutputFormat, Z as CaseComparisonResult, _ as ClientCredentialsConfig, $ as CompareEvalRunsOptions, a0 as ComparisonOutcome, a1 as ContentBlock, a2 as CreateMCPClientOptions, a3 as CustomJudgeExecutor, a4 as CustomJudgeResult, a9 as EvalCase, aa as EvalCaseComparison, ab as EvalCaseComparisonOutcome, ac as EvalCaseRequest, l as EvalCaseResult, ae as EvalContext, o as EvalDataset, ag as EvalExpectBlock, ah as EvalExpectationResult, ak as EvalMode, ao as EvalRunComparisonLabels, ap as EvalRunComparisonResult, aq as EvalRunMetadata, ar as EvalRunnerOptions, r as EvalRunnerResult, ay as ExpectationBreakdown, az as ExpectationResultMap, aA as ExpectationType, aB as ExperimentMetric, aJ as FieldRemovalSanitizer, aT as HostDiagnostics, a_ as HostType, a$ as HttpMCPConfig, b0 as IterationResult, G as Judge, F as JudgeConfig, b1 as JudgeExpectConfig, J as JudgeMatcherOptions, b2 as JudgeResult, b3 as JudgeValidatorConfig, L as LLMProvider, b4 as LLMToolCall, b6 as LoadDatasetOptions, b7 as MCPAuthConfig, b8 as MCPAuthFixtures, b9 as MCPClientCredentialsConfig, p as MCPConfig, bb as MCPConformanceCheck, bc as MCPConformanceOptions, bd as MCPConformanceRaw, be as MCPConformanceResult, bf as MCPConformanceResultData, bg as MCPEvalData, bh as MCPEvalHistoricalSummary, bi as MCPEvalReporterConfig, bj as MCPEvalRunData, M as MCPFixtureApi, bk as MCPFixtureOptions, bl as MCPHostCapabilities, a as MCPHostConfig, b as MCPHostSimulationResult, bm as MCPHostSimulator, bn as MCPOAuthConfig, bo as MCPServerCapabilitiesData, br as NormalizedToolResponse, O as OAuthSetupConfig, P as PatternValidatorOptions, bu as PlaywrightOAuthClientProviderConfig, bv as PredicateResult, bw as ProposeVariantsContext, bx as ProtectedResourceDiscoveryResult, by as ProtectedResourceMetadata, bz as ProviderKind, bA as RegexSanitizer, bB as ResultSource, R as RubricSpec, bE as SaveBaselineOptions, bF as SaveEvalRunComparisonOptions, bG as SaveServerComparisonOptions, bH as SchemaRegistry, S as SchemaValidatorOptions, bI as SerializedEvalDataset, bJ as ServerComparisonOptions, bK as ServerComparisonResult, c as SizeValidatorOptions, d as SnapshotSanitizer, bL as SnapshotSanitizers, bM as StdioMCPConfig, bP as StoredClientInfo, bS as StoredEvalResultLoadOptions, bT as StoredEvalResultRef, bU as StoredEvalResultSaveOptions, bV as StoredEvalRunRef, bW as StoredOAuthState, bX as StoredServerMetadata, bY as StoredTokens, T as TextValidatorOptions, b_ as TokenResult, g as ToolCallCountOptions, f as ToolCallExpectation, b$ as ToolMetadataOverride, c0 as ToolOverrideVariant, e as ToolPredicate, c2 as UsageMetrics, V as ValidationResult, c3 as VariantCandidateResult, c4 as VariantExperimentOptions, c5 as VariantExperimentReason, c6 as VariantExperimentResult, c7 as VariantExperimentRound, c8 as VariantImprovementProposal, c9 as VariantRecommendation } from '../index-CwFHKIoN.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import '@playwright/test';
|
|
4
|
+
import '@modelcontextprotocol/sdk/client/index.js';
|
|
5
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
4
6
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
5
7
|
import '@modelcontextprotocol/sdk/shared/auth.js';
|
|
6
8
|
import 'oauth4webapi';
|
|
7
|
-
import '@modelcontextprotocol/sdk/client/index.js';
|
|
8
|
-
import '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import 'playwright/test';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gleanwork/mcp-server-tester",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "Playwright-based testing and evaluation framework for MCP servers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"playwright",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"import": "./dist/index.js",
|
|
29
29
|
"require": "./dist/index.cjs"
|
|
30
30
|
},
|
|
31
|
+
"./cowork-runtime": "./scripts/cowork_computer_use.py",
|
|
32
|
+
"./cowork-requirements": "./scripts/cowork-requirements.txt",
|
|
31
33
|
"./types": {
|
|
32
34
|
"types": "./dist/types/index.d.ts",
|
|
33
35
|
"import": "./dist/types/index.js",
|
|
@@ -54,12 +56,14 @@
|
|
|
54
56
|
"mcp-server-tester": "./dist/cli/index.js"
|
|
55
57
|
},
|
|
56
58
|
"files": [
|
|
57
|
-
"dist"
|
|
59
|
+
"dist",
|
|
60
|
+
"scripts/cowork_computer_use.py",
|
|
61
|
+
"scripts/cowork-requirements.txt"
|
|
58
62
|
],
|
|
59
63
|
"scripts": {
|
|
60
64
|
"build": "npm run build:ui && tsup && npm run build:copy-ui",
|
|
61
65
|
"build:copy-ui": "cp -r src/reporters/ui-dist dist/reporters/",
|
|
62
|
-
"build:ui": "tsx src/reporters/build-ui.ts",
|
|
66
|
+
"build:ui": "node --import tsx src/reporters/build-ui.ts",
|
|
63
67
|
"dev": "tsup --watch",
|
|
64
68
|
"dev:ui": "tsx src/reporters/build-ui.ts --watch",
|
|
65
69
|
"format": "prettier --write \"**/*.{ts,tsx,json,md}\"",
|
|
@@ -71,7 +75,11 @@
|
|
|
71
75
|
"docs:sync": "markdown-code sync",
|
|
72
76
|
"preview-reporter": "tsx scripts/preview-reporter.ts",
|
|
73
77
|
"test": "vitest run",
|
|
78
|
+
"test:eval-foundation": "node scripts/test-eval-foundation.mjs",
|
|
74
79
|
"test:all": "npm run build && npm run format:check && npm run lint && npm run typecheck && npm test",
|
|
80
|
+
"test:external-host": "vitest run --config vitest.external-host.config.mts",
|
|
81
|
+
"test:external-host:chat": "vitest run --config vitest.external-host.config.mts -t \"Claude Chat\"",
|
|
82
|
+
"test:external-host:cowork": "vitest run --config vitest.external-host.config.mts -t \"Claude Cowork\"",
|
|
75
83
|
"test:playwright": "playwright test",
|
|
76
84
|
"test:watch": "vitest",
|
|
77
85
|
"typecheck": "tsc --noEmit"
|
|
@@ -84,6 +92,7 @@
|
|
|
84
92
|
"debug": "^4.4.3",
|
|
85
93
|
"ink": "^5.2.1",
|
|
86
94
|
"ink-spinner": "^5.0.0",
|
|
95
|
+
"ndjson": "^2.0.0",
|
|
87
96
|
"oauth4webapi": "^3.0.0",
|
|
88
97
|
"open": "^10.1.0",
|
|
89
98
|
"react": "^18.3.1",
|
|
@@ -93,8 +102,10 @@
|
|
|
93
102
|
"devDependencies": {
|
|
94
103
|
"@ai-sdk/provider-utils": "^4.0.15",
|
|
95
104
|
"@playwright/test": "^1.49.0",
|
|
105
|
+
"playwright": "^1.57.0",
|
|
96
106
|
"@release-it-plugins/lerna-changelog": "^8.0.1",
|
|
97
107
|
"@types/debug": "^4.1.12",
|
|
108
|
+
"@types/ndjson": "^2.0.4",
|
|
98
109
|
"@types/node": "^22.10.2",
|
|
99
110
|
"@types/react": "^18.3.12",
|
|
100
111
|
"@types/react-dom": "^18.3.1",
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Submit one Claude Cowork query through a bounded screenshot/action loop.
|
|
3
|
+
|
|
4
|
+
The process stops immediately after the first submit key. MST owns native-session
|
|
5
|
+
correlation, terminal validation, response extraction, and telemetry collection.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import asyncio
|
|
12
|
+
import base64
|
|
13
|
+
import io
|
|
14
|
+
import json
|
|
15
|
+
import math
|
|
16
|
+
import os
|
|
17
|
+
import re
|
|
18
|
+
import subprocess
|
|
19
|
+
import sys
|
|
20
|
+
import time
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
DISPLAY_WIDTH = 1280
|
|
24
|
+
DISPLAY_HEIGHT = 800
|
|
25
|
+
DEFAULT_MODEL = "claude-sonnet-4-6"
|
|
26
|
+
DEFAULT_MAX_ACTIONS = 24
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def log(message: str) -> None:
|
|
30
|
+
print(f"[mst:cowork-cu] {message}", file=sys.stderr, flush=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def screenshot() -> dict[str, Any]:
|
|
34
|
+
import mss
|
|
35
|
+
from PIL import Image
|
|
36
|
+
|
|
37
|
+
with mss.MSS() as capture:
|
|
38
|
+
monitor = capture.monitors[1]
|
|
39
|
+
raw = capture.grab(monitor)
|
|
40
|
+
image = Image.frombytes("RGB", raw.size, raw.bgra, "raw", "BGRX")
|
|
41
|
+
image = image.resize((DISPLAY_WIDTH, DISPLAY_HEIGHT), Image.Resampling.LANCZOS)
|
|
42
|
+
buffer = io.BytesIO()
|
|
43
|
+
image.save(buffer, format="PNG")
|
|
44
|
+
return {
|
|
45
|
+
"type": "image",
|
|
46
|
+
"source": {
|
|
47
|
+
"type": "base64",
|
|
48
|
+
"media_type": "image/png",
|
|
49
|
+
"data": base64.standard_b64encode(buffer.getvalue()).decode("ascii"),
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def screen_point(coordinate: list[int]) -> tuple[int, int]:
|
|
55
|
+
import pyautogui
|
|
56
|
+
|
|
57
|
+
width, height = pyautogui.size() # Logical points, not Retina capture pixels.
|
|
58
|
+
return (
|
|
59
|
+
int(coordinate[0] * width / DISPLAY_WIDTH),
|
|
60
|
+
int(coordinate[1] * height / DISPLAY_HEIGHT),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def type_query(text: str) -> None:
|
|
65
|
+
"""Unicode keyboard events; line breaks must not submit the composer."""
|
|
66
|
+
import Quartz
|
|
67
|
+
import pyautogui
|
|
68
|
+
|
|
69
|
+
for line_index, line in enumerate(text.split("\n")):
|
|
70
|
+
if line_index:
|
|
71
|
+
pyautogui.hotkey("shift", "enter")
|
|
72
|
+
for start in range(0, len(line), 16):
|
|
73
|
+
chunk = line[start:start + 16]
|
|
74
|
+
units = len(chunk.encode("utf-16-le")) // 2
|
|
75
|
+
for down in (True, False):
|
|
76
|
+
event = Quartz.CGEventCreateKeyboardEvent(None, 0, down)
|
|
77
|
+
Quartz.CGEventKeyboardSetUnicodeString(event, units, chunk)
|
|
78
|
+
Quartz.CGEventPost(Quartz.kCGHIDEventTap, event)
|
|
79
|
+
time.sleep(0.01)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def execute_action(action: dict[str, Any]) -> tuple[Any, bool]:
|
|
83
|
+
import pyautogui
|
|
84
|
+
|
|
85
|
+
name = action.get("action")
|
|
86
|
+
if name == "screenshot":
|
|
87
|
+
return screenshot(), False
|
|
88
|
+
if name in {
|
|
89
|
+
"left_click",
|
|
90
|
+
"right_click",
|
|
91
|
+
"middle_click",
|
|
92
|
+
"double_click",
|
|
93
|
+
"triple_click",
|
|
94
|
+
}:
|
|
95
|
+
x, y = screen_point(action["coordinate"])
|
|
96
|
+
button = {
|
|
97
|
+
"right_click": "right",
|
|
98
|
+
"middle_click": "middle",
|
|
99
|
+
}.get(name, "left")
|
|
100
|
+
clicks = {
|
|
101
|
+
"double_click": 2,
|
|
102
|
+
"triple_click": 3,
|
|
103
|
+
}.get(name, 1)
|
|
104
|
+
pyautogui.click(x, y, clicks=clicks, button=button)
|
|
105
|
+
return f"{name} completed", False
|
|
106
|
+
if name == "cursor_position":
|
|
107
|
+
x, y = pyautogui.position()
|
|
108
|
+
return {"x": int(x), "y": int(y)}, False
|
|
109
|
+
if name == "mouse_move":
|
|
110
|
+
x, y = screen_point(action["coordinate"])
|
|
111
|
+
pyautogui.moveTo(x, y)
|
|
112
|
+
return "mouse_move completed", False
|
|
113
|
+
if name == "left_click_drag":
|
|
114
|
+
start_x, start_y = screen_point(action["start_coordinate"])
|
|
115
|
+
end_x, end_y = screen_point(action["coordinate"])
|
|
116
|
+
pyautogui.moveTo(start_x, start_y)
|
|
117
|
+
pyautogui.dragTo(end_x, end_y, duration=0.4, button="left")
|
|
118
|
+
return "drag completed", False
|
|
119
|
+
if name == "type":
|
|
120
|
+
type_query(action["text"])
|
|
121
|
+
return "text entered", False
|
|
122
|
+
if name == "key":
|
|
123
|
+
text = str(action["text"])
|
|
124
|
+
aliases = {"return": "enter", "super": "command", "cmd": "command", "ctrl": "ctrl"}
|
|
125
|
+
keys = [aliases.get(part.strip().lower(), part.strip().lower()) for part in text.split("+")]
|
|
126
|
+
if len(keys) == 1:
|
|
127
|
+
pyautogui.press(keys[0])
|
|
128
|
+
else:
|
|
129
|
+
pyautogui.hotkey(*keys)
|
|
130
|
+
submitted = any(key in {"enter", "return"} for key in keys)
|
|
131
|
+
return f"key completed: {text}", submitted
|
|
132
|
+
if name == "scroll":
|
|
133
|
+
x, y = screen_point(action.get("coordinate", [DISPLAY_WIDTH // 2, DISPLAY_HEIGHT // 2]))
|
|
134
|
+
amount = int(action.get("scroll_amount", 3))
|
|
135
|
+
direction = action.get("scroll_direction", "down")
|
|
136
|
+
pyautogui.moveTo(x, y)
|
|
137
|
+
pyautogui.scroll(-amount if direction == "down" else amount)
|
|
138
|
+
return "scroll completed", False
|
|
139
|
+
if name == "wait":
|
|
140
|
+
time.sleep(min(float(action.get("duration", 1)), 5.0))
|
|
141
|
+
return "wait completed", False
|
|
142
|
+
raise RuntimeError(f"unsupported Computer Use action: {name}")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
TOKEN_FIELDS = (
|
|
146
|
+
"input_tokens", "output_tokens", "cache_creation_input_tokens", "cache_read_input_tokens",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class ComputerUseDriverError(RuntimeError):
|
|
151
|
+
def __init__(self, message: str, telemetry: dict[str, Any]):
|
|
152
|
+
super().__init__(message)
|
|
153
|
+
self.telemetry = telemetry
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class Telemetry:
|
|
157
|
+
"""Only completed API responses and allowlisted scalar data; never request content."""
|
|
158
|
+
|
|
159
|
+
def __init__(self) -> None:
|
|
160
|
+
self.started = time.monotonic()
|
|
161
|
+
self.models: list[str] = []
|
|
162
|
+
self.responses = 0
|
|
163
|
+
self.usage: dict[str, int | float] = {}
|
|
164
|
+
self.coverage = {field: 0 for field in TOKEN_FIELDS}
|
|
165
|
+
self.actions = 0
|
|
166
|
+
self.attempted = 0
|
|
167
|
+
self.executed = 0
|
|
168
|
+
self.refused = 0
|
|
169
|
+
|
|
170
|
+
def observe(self, response: Any) -> None:
|
|
171
|
+
self.responses += 1
|
|
172
|
+
model = getattr(response, "model", None)
|
|
173
|
+
secrets = [value for key, value in os.environ.items()
|
|
174
|
+
if value and re.search(r"token|key|secret|password|authorization", key, re.I)]
|
|
175
|
+
if (isinstance(model, str) and re.fullmatch(r"claude-[a-z0-9][a-z0-9.-]{0,99}", model)
|
|
176
|
+
and not any(secret in model for secret in secrets) and model not in self.models):
|
|
177
|
+
self.models.append(model)
|
|
178
|
+
usage = getattr(response, "usage", None)
|
|
179
|
+
for field in TOKEN_FIELDS:
|
|
180
|
+
value = getattr(usage, field, None)
|
|
181
|
+
if (type(value) in (int, float) and 0 <= value <= 9007199254740991
|
|
182
|
+
and math.isfinite(value) and value == int(value)):
|
|
183
|
+
total = self.usage.get(field, 0) + value
|
|
184
|
+
if total <= 9007199254740991:
|
|
185
|
+
self.usage[field] = total
|
|
186
|
+
self.coverage[field] += 1
|
|
187
|
+
|
|
188
|
+
def snapshot(self, accounting: str) -> dict[str, Any]:
|
|
189
|
+
return {
|
|
190
|
+
"accounting": accounting,
|
|
191
|
+
"response_models": list(self.models),
|
|
192
|
+
"planner_response_count": self.responses,
|
|
193
|
+
"usage": dict(self.usage),
|
|
194
|
+
"usage_observation_counts": dict(self.coverage),
|
|
195
|
+
"duration_ms": max(0, (time.monotonic() - self.started) * 1000),
|
|
196
|
+
"action_count": self.actions,
|
|
197
|
+
"attempted_action_count": self.attempted,
|
|
198
|
+
"executed_action_count": self.executed,
|
|
199
|
+
"refused_action_count": self.refused,
|
|
200
|
+
# Anthropic Messages usage does not supply authoritative dollar cost.
|
|
201
|
+
"cost": {"status": "unavailable"},
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
async def run(query: str, max_actions: int, mode: str) -> dict[str, Any]:
|
|
206
|
+
telemetry = Telemetry()
|
|
207
|
+
try:
|
|
208
|
+
result = await run_driver(query, max_actions, mode, telemetry)
|
|
209
|
+
result["telemetry"] = telemetry.snapshot("complete")
|
|
210
|
+
return result
|
|
211
|
+
except Exception as error:
|
|
212
|
+
raise ComputerUseDriverError(str(error), telemetry.snapshot("partial")) from error
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
async def run_driver(query: str, max_actions: int, mode: str, telemetry: Telemetry) -> dict[str, Any]:
|
|
216
|
+
try:
|
|
217
|
+
import anthropic
|
|
218
|
+
except ImportError as error:
|
|
219
|
+
raise RuntimeError("Install the Computer Use dependencies: pip install anthropic pyautogui mss Pillow") from error
|
|
220
|
+
|
|
221
|
+
api_key = os.environ.get("ANTHROPIC_API_KEY")
|
|
222
|
+
if not api_key:
|
|
223
|
+
raise RuntimeError("ANTHROPIC_API_KEY is required for the Computer Use submission driver")
|
|
224
|
+
|
|
225
|
+
client = anthropic.Anthropic(api_key=api_key)
|
|
226
|
+
model = os.environ.get("MST_COWORK_CUA_MODEL", DEFAULT_MODEL)
|
|
227
|
+
log(f"starting driver with model={model}, max_actions={max_actions}")
|
|
228
|
+
subprocess.run(["open", "-a", "Claude"], check=False, capture_output=True)
|
|
229
|
+
log("requested Claude Desktop launch/focus")
|
|
230
|
+
time.sleep(float(os.environ.get("MST_COWORK_CUA_START_DELAY", "3")))
|
|
231
|
+
|
|
232
|
+
tools = [{
|
|
233
|
+
"type": "computer_20251124",
|
|
234
|
+
"name": "computer",
|
|
235
|
+
"display_width_px": DISPLAY_WIDTH,
|
|
236
|
+
"display_height_px": DISPLAY_HEIGHT,
|
|
237
|
+
}]
|
|
238
|
+
if mode == "hitl":
|
|
239
|
+
messages: list[dict[str, Any]] = [{
|
|
240
|
+
"role": "user",
|
|
241
|
+
"content": (
|
|
242
|
+
"Inspect the currently visible Claude Desktop Cowork task. If a human-in-the-loop "
|
|
243
|
+
"approval or choice prompt is blocking progress, choose the first visible option. "
|
|
244
|
+
"Do not submit a new query, do not change account settings, and do not approve a "
|
|
245
|
+
"prompt unless it is the visible task's first option. If no such prompt is visible, "
|
|
246
|
+
"stop without taking an action.\n\nTask to locate (do not type or submit this text):\n" + query
|
|
247
|
+
),
|
|
248
|
+
}]
|
|
249
|
+
system = (
|
|
250
|
+
"You are a bounded HITL resolver. Use screenshots and Computer Use actions only. "
|
|
251
|
+
"Choose the first visible option when a task approval/choice prompt is present. "
|
|
252
|
+
"Never submit a query or change account settings. If no HITL prompt is visible, stop."
|
|
253
|
+
)
|
|
254
|
+
else:
|
|
255
|
+
tools.append({
|
|
256
|
+
"name": "fill_query",
|
|
257
|
+
"description": (
|
|
258
|
+
"Insert the unchanged original evaluation query into the focused "
|
|
259
|
+
"empty Cowork task composer. First locate and focus that composer using a screenshot. "
|
|
260
|
+
"This tool takes no text: the harness supplies the exact text. It may run only once. "
|
|
261
|
+
"After it succeeds, use computer key Enter to submit, never click Send."
|
|
262
|
+
),
|
|
263
|
+
"input_schema": {"type": "object", "properties": {}, "additionalProperties": False},
|
|
264
|
+
})
|
|
265
|
+
messages = [{
|
|
266
|
+
"role": "user",
|
|
267
|
+
"content": (
|
|
268
|
+
"Control Claude Desktop. Open Cowork, create a fresh task, and focus its empty "
|
|
269
|
+
"prompt composer. Call fill_query with no arguments. It inserts the original "
|
|
270
|
+
"query for you. Do not reconstruct or type the query yourself. Then press "
|
|
271
|
+
"unmodified Enter once to submit. Do not wait for or read the answer."
|
|
272
|
+
),
|
|
273
|
+
}]
|
|
274
|
+
system = (
|
|
275
|
+
"You are a bounded desktop submission operator. Use screenshots and Computer Use "
|
|
276
|
+
"actions to open/focus Claude, select Cowork, create a fresh task, and focus its composer. "
|
|
277
|
+
"Use fill_query, not computer type, to insert the query. After fill_query succeeds, "
|
|
278
|
+
"submit with unmodified Enter, never by clicking Send. Never submit twice. Stop after "
|
|
279
|
+
"submission. Do not approve permissions or change account settings."
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
# Ground the first action in a current screenshot, not an assumed layout.
|
|
283
|
+
messages[0]["content"] = [{"type": "text", "text": messages[0]["content"]}, screenshot()]
|
|
284
|
+
hitl_action_taken = False
|
|
285
|
+
actions_executed = 0
|
|
286
|
+
typed_query = False
|
|
287
|
+
for action_number in range(1, max_actions + 1):
|
|
288
|
+
log(f"requesting Computer Use plan {action_number}/{max_actions}")
|
|
289
|
+
response = client.beta.messages.create(
|
|
290
|
+
model=model,
|
|
291
|
+
max_tokens=1024,
|
|
292
|
+
system=system,
|
|
293
|
+
tools=tools,
|
|
294
|
+
messages=messages,
|
|
295
|
+
betas=["computer-use-2025-11-24"],
|
|
296
|
+
)
|
|
297
|
+
telemetry.observe(response)
|
|
298
|
+
messages.append({"role": "assistant", "content": response.content})
|
|
299
|
+
tool_results: list[dict[str, Any]] = []
|
|
300
|
+
for block in response.content:
|
|
301
|
+
if getattr(block, "type", None) != "tool_use":
|
|
302
|
+
continue
|
|
303
|
+
if actions_executed >= max_actions:
|
|
304
|
+
raise RuntimeError("Computer Use action budget exhausted; no further actions executed")
|
|
305
|
+
actions_executed += 1
|
|
306
|
+
telemetry.actions += 1
|
|
307
|
+
tool_name = getattr(block, "name", "computer")
|
|
308
|
+
action = block.input
|
|
309
|
+
action_name = action.get('action', 'unknown')
|
|
310
|
+
refusal = None
|
|
311
|
+
if mode == "hitl" and (tool_name != "computer" or action_name not in {"screenshot", "wait", "mouse_move", "cursor_position", "left_click", "scroll"}):
|
|
312
|
+
telemetry.refused += 1
|
|
313
|
+
raise RuntimeError("HITL cannot type, press keys, drag, or submit tasks")
|
|
314
|
+
if mode == "submit":
|
|
315
|
+
if tool_name == "fill_query":
|
|
316
|
+
if typed_query:
|
|
317
|
+
refusal = "The query is already entered. Do not fill again. Use unmodified Enter to submit."
|
|
318
|
+
elif block.input != {}:
|
|
319
|
+
refusal = "fill_query takes no arguments; the harness owns the original text."
|
|
320
|
+
else:
|
|
321
|
+
action = {"action": "type", "text": query}
|
|
322
|
+
action_name = "type"
|
|
323
|
+
elif tool_name != "computer":
|
|
324
|
+
refusal = "Unknown tool. Use computer for navigation and fill_query for text entry."
|
|
325
|
+
elif action_name == "type":
|
|
326
|
+
refusal = "Do not reconstruct the query. Focus the empty composer, then call fill_query with no arguments."
|
|
327
|
+
elif action_name == "key" and any(k.strip().lower() in {"enter", "return"} for k in str(action.get("text", "")).split("+")):
|
|
328
|
+
if not typed_query or str(action.get("text", "")).lower() not in {"enter", "return"}:
|
|
329
|
+
refusal = "Only an unmodified Enter after fill_query succeeds may submit."
|
|
330
|
+
elif typed_query and action_name not in {"screenshot", "wait", "cursor_position"}:
|
|
331
|
+
refusal = "The query is entered. Only screenshots or the single Enter submission are allowed."
|
|
332
|
+
if refusal:
|
|
333
|
+
telemetry.refused += 1
|
|
334
|
+
# A rejected proposal has no desktop side effects. Let the planner correct it
|
|
335
|
+
# within the same action budget; never retry a failed physical text entry.
|
|
336
|
+
tool_results.append({"type": "tool_result", "tool_use_id": block.id, "content": refusal, "is_error": True})
|
|
337
|
+
continue
|
|
338
|
+
log(f"executing action {actions_executed}: {action_name}")
|
|
339
|
+
if mode == "hitl" and action_name not in {
|
|
340
|
+
"screenshot",
|
|
341
|
+
"wait",
|
|
342
|
+
"mouse_move",
|
|
343
|
+
"cursor_position",
|
|
344
|
+
}:
|
|
345
|
+
hitl_action_taken = True
|
|
346
|
+
telemetry.attempted += 1
|
|
347
|
+
result, submitted = execute_action(action)
|
|
348
|
+
telemetry.executed += 1
|
|
349
|
+
if tool_name == "fill_query":
|
|
350
|
+
typed_query = True
|
|
351
|
+
if submitted and mode != "hitl":
|
|
352
|
+
log("submission boundary reached; stopping immediately")
|
|
353
|
+
return {
|
|
354
|
+
"status": "submitted",
|
|
355
|
+
"action_count": actions_executed,
|
|
356
|
+
"model": model,
|
|
357
|
+
"submission_action": {"action": "key", "text": "enter"},
|
|
358
|
+
}
|
|
359
|
+
if isinstance(result, dict) and result.get("type") == "image":
|
|
360
|
+
tool_content: Any = [result]
|
|
361
|
+
else:
|
|
362
|
+
tool_content = str(result)
|
|
363
|
+
tool_results.append({
|
|
364
|
+
"type": "tool_result",
|
|
365
|
+
"tool_use_id": block.id,
|
|
366
|
+
"content": tool_content,
|
|
367
|
+
})
|
|
368
|
+
if not tool_results:
|
|
369
|
+
if mode == "hitl":
|
|
370
|
+
log("no HITL action was needed")
|
|
371
|
+
return {"status": "hitl_checked", "action_count": actions_executed, "model": model}
|
|
372
|
+
raise RuntimeError("Computer Use planner stopped before submitting the Cowork query")
|
|
373
|
+
messages.append({"role": "user", "content": tool_results})
|
|
374
|
+
|
|
375
|
+
if mode == "hitl" and not hitl_action_taken:
|
|
376
|
+
log("no visible HITL prompt found within the bounded check")
|
|
377
|
+
return {
|
|
378
|
+
"status": "hitl_checked",
|
|
379
|
+
"action_count": actions_executed,
|
|
380
|
+
"prompt_found": False,
|
|
381
|
+
"model": model,
|
|
382
|
+
}
|
|
383
|
+
if mode == "hitl":
|
|
384
|
+
raise RuntimeError(
|
|
385
|
+
f"Computer Use HITL check exceeded {max_actions} actions after attempting a visible prompt"
|
|
386
|
+
)
|
|
387
|
+
raise RuntimeError(f"Computer Use submission exceeded {max_actions} actions without submitting")
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def main() -> int:
|
|
391
|
+
parser = argparse.ArgumentParser()
|
|
392
|
+
parser.add_argument("query")
|
|
393
|
+
parser.add_argument("--max-actions", type=int, default=DEFAULT_MAX_ACTIONS)
|
|
394
|
+
parser.add_argument("--mode", choices=["submit", "hitl"], default="submit")
|
|
395
|
+
args = parser.parse_args()
|
|
396
|
+
try:
|
|
397
|
+
print(json.dumps(asyncio.run(run(args.query, args.max_actions, args.mode))), flush=True)
|
|
398
|
+
return 0
|
|
399
|
+
except Exception as error:
|
|
400
|
+
log(f"driver failed: {error}")
|
|
401
|
+
result = {"status": "failed", "error": str(error)}
|
|
402
|
+
if isinstance(error, ComputerUseDriverError):
|
|
403
|
+
result["telemetry"] = error.telemetry
|
|
404
|
+
print(json.dumps(result), flush=True)
|
|
405
|
+
return 1
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
if __name__ == "__main__":
|
|
409
|
+
sys.exit(main())
|