conductor-remote 1.37.0 → 1.39.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.
@@ -0,0 +1 @@
1
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-outline-style:solid;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, -apple-system, "SF Pro Text", "Segoe UI", Roboto, sans-serif;--font-mono:ui-monospace, "SF Mono", "JetBrains Mono", "Fira Code", Menlo, monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#0a0b0e;--color-surface:#14161b;--color-surface-2:#1b1e26;--color-border:#262a33;--color-border-soft:#1e222a;--color-text:#e7e9ee;--color-muted:#8b909d;--color-faint:#5c616d;--color-accent:#8b7dff;--color-accent-soft:#2a2650;--color-working:#f5a623;--color-idle:#3ecf8e;--color-done:#5b9dff;--color-pr-merged:#ac47ff;--color-pr-draft:#a4a3a2;--color-pr-conflicts:#fd9a00;--color-pr-mergeable:#49de80;--color-add:#3ecf8e;--color-del:#ff6b6b}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{-webkit-tap-highlight-color:transparent}html,body,#root{height:var(--app-height,100dvh)}html,body{overflow:hidden}@media(display-mode:standalone){html,body,#root{height:var(--app-height,100vh)}}html[data-standalone],html[data-standalone] body,html[data-standalone] #root{height:var(--app-height,100vh)}html{background:var(--color-bg)}body{background:var(--color-bg);color:var(--color-text);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;overscroll-behavior:none;margin:0}button{font:inherit;color:inherit;cursor:pointer}::-webkit-scrollbar{width:0;height:0}}@layer components{.card{align-items:center;gap:calc(var(--spacing) * 3);border-radius:var(--radius-2xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border);background-color:var(--color-surface);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3.5);text-align:left;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));display:flex}.card:active{background-color:var(--color-surface-2);scale:.985}.pill{padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:3.40282e38px}.pill-active{background-color:var(--color-surface-2);color:var(--color-text)}.ctl{padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);--tw-font-weight:var(--font-weight-medium);font-size:13px;font-weight:var(--font-weight-medium);color:var(--color-muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:3.40282e38px}.ctl-on{background-color:var(--color-surface-2);color:var(--color-text)}.ctl-staged{background-color:var(--color-accent-soft);color:var(--color-accent)}.dot{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);background-color:var(--color-faint);border-radius:3.40282e38px;flex-shrink:0}.dot-spinner{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5);animation:var(--animate-spin);border-style:var(--tw-border-style);--spin-color:var(--color-working);border-width:2px;border-color:var(--spin-color);border-radius:3.40282e38px;flex-shrink:0}@supports (color:color-mix(in lab,red,red)){.dot-spinner{border-color:color-mix(in srgb,var(--spin-color) 30%,transparent)}}.dot-spinner{border-top-color:var(--spin-color);border-right-color:var(--spin-color)}.dot-idle{background:var(--color-idle)}.dot-done{background:var(--color-done)}.typing-dot{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5);background-color:var(--color-muted);border-radius:3.40282e38px;animation:1.2s ease-in-out infinite typing}.typing-dot:nth-child(2){animation-delay:.15s}.typing-dot:nth-child(3){animation-delay:.3s}.md>:first-child{margin-top:0}.md>:last-child{margin-bottom:0}.md p{margin:.5em 0}.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{margin:.9em 0 .4em;font-weight:600;line-height:1.3}.md h1{font-size:1.25em}.md h2{font-size:1.15em}.md h3{font-size:1.05em}.md ul,.md ol{margin:.5em 0;padding-left:1.4em}.md ul{list-style:outside}.md ol{list-style:decimal}.md li,.md li>ul,.md li>ol{margin:.2em 0}.md code{background:#1b1e26cc;border-radius:.3rem}@supports (color:color-mix(in lab,red,red)){.md code{background:color-mix(in srgb,var(--color-surface-2) 80%,transparent)}}.md code{font-family:var(--font-mono);padding:.1em .35em;font-size:.85em}.md pre{border:1px solid var(--color-border-soft);background:var(--color-bg);border-radius:.6rem;margin:.5em 0;padding:.6em .75em;overflow-x:auto}.md pre code{background:0 0;padding:0;font-size:12px;line-height:1.5}.md a{color:var(--color-accent);text-underline-offset:2px;text-decoration:underline}.md blockquote{border-left:2px solid var(--color-border);color:var(--color-muted);margin:.5em 0;padding-left:.75em}.md hr{border:0;border-top:1px solid var(--color-border-soft);margin:.75em 0}.md table{border-collapse:collapse;max-width:100%;margin:.5em 0;font-size:.9em;display:block;overflow-x:auto}.md th,.md td{border:1px solid var(--color-border);text-align:left;padding:.3em .6em}.md th{background:var(--color-surface-2);font-weight:600}.md strong{font-weight:600}.md input[type=checkbox]{margin-right:.4em}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-full{top:100%}.-right-0\.5{right:calc(var(--spacing) * -.5)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.-bottom-0\.5{bottom:calc(var(--spacing) * -.5)}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-0\.5{left:calc(var(--spacing) * .5)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.-mr-1{margin-right:calc(var(--spacing) * -1)}.-mr-2{margin-right:calc(var(--spacing) * -2)}.mr-1{margin-right:var(--spacing)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-4{-webkit-line-clamp:4;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.size-20{width:calc(var(--spacing) * 20);height:calc(var(--spacing) * 20)}.size-60{width:calc(var(--spacing) * 60);height:calc(var(--spacing) * 60)}.size-full{width:100%;height:100%}.h-6{height:calc(var(--spacing) * 6)}.h-12{height:calc(var(--spacing) * 12)}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-\[70\%\]{max-height:70%}.max-h-\[85dvh\]{max-height:85dvh}.min-h-0{min-height:0}.min-h-14{min-height:calc(var(--spacing) * 14)}.w-1{width:var(--spacing)}.w-5{width:calc(var(--spacing) * 5)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-44{width:calc(var(--spacing) * 44)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-\[85\%\]{width:85%}.w-full{width:100%}.max-w-36{max-width:calc(var(--spacing) * 36)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-\[55vw\]{max-width:55vw}.max-w-\[70vw\]{max-width:70vw}.max-w-\[85\%\]{max-width:85%}.max-w-\[92\%\]{max-width:92%}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-0{--tw-translate-y:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-3{--tw-translate-y:calc(var(--spacing) * 3);translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.scrollbar-thin{scrollbar-width:thin}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-2xl{border-top-left-radius:var(--radius-2xl);border-top-right-radius:var(--radius-2xl)}.rounded-t-3xl{border-top-left-radius:var(--radius-3xl);border-top-right-radius:var(--radius-3xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-accent\/50{border-color:#8b7dff80}@supports (color:color-mix(in lab,red,red)){.border-accent\/50{border-color:color-mix(in oklab,var(--color-accent) 50%,transparent)}}.border-border{border-color:var(--color-border)}.border-border-soft{border-color:var(--color-border-soft)}.border-del\/30{border-color:#ff6b6b4d}@supports (color:color-mix(in lab,red,red)){.border-del\/30{border-color:color-mix(in oklab,var(--color-del) 30%,transparent)}}.border-del\/40{border-color:#ff6b6b66}@supports (color:color-mix(in lab,red,red)){.border-del\/40{border-color:color-mix(in oklab,var(--color-del) 40%,transparent)}}.border-faint{border-color:var(--color-faint)}.border-white\/80{border-color:#fffc}@supports (color:color-mix(in lab,red,red)){.border-white\/80{border-color:color-mix(in oklab,var(--color-white) 80%,transparent)}}.border-t-accent{border-top-color:var(--color-accent)}.border-t-text{border-top-color:var(--color-text)}.border-l-accent{border-left-color:var(--color-accent)}.bg-accent{background-color:var(--color-accent)}.bg-accent-soft{background-color:var(--color-accent-soft)}.bg-accent\/10{background-color:#8b7dff1a}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--color-accent) 10%,transparent)}}.bg-add{background-color:var(--color-add)}.bg-add\/10{background-color:#3ecf8e1a}@supports (color:color-mix(in lab,red,red)){.bg-add\/10{background-color:color-mix(in oklab,var(--color-add) 10%,transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-bg\/80{background-color:#0a0b0ecc}@supports (color:color-mix(in lab,red,red)){.bg-bg\/80{background-color:color-mix(in oklab,var(--color-bg) 80%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-black\/75{background-color:#000000bf}@supports (color:color-mix(in lab,red,red)){.bg-black\/75{background-color:color-mix(in oklab,var(--color-black) 75%,transparent)}}.bg-del{background-color:var(--color-del)}.bg-del\/5{background-color:#ff6b6b0d}@supports (color:color-mix(in lab,red,red)){.bg-del\/5{background-color:color-mix(in oklab,var(--color-del) 5%,transparent)}}.bg-del\/10{background-color:#ff6b6b1a}@supports (color:color-mix(in lab,red,red)){.bg-del\/10{background-color:color-mix(in oklab,var(--color-del) 10%,transparent)}}.bg-del\/15{background-color:#ff6b6b26}@supports (color:color-mix(in lab,red,red)){.bg-del\/15{background-color:color-mix(in oklab,var(--color-del) 15%,transparent)}}.bg-pr-merged\/10{background-color:#ac47ff1a}@supports (color:color-mix(in lab,red,red)){.bg-pr-merged\/10{background-color:color-mix(in oklab,var(--color-pr-merged) 10%,transparent)}}.bg-pr-merged\/15{background-color:#ac47ff26}@supports (color:color-mix(in lab,red,red)){.bg-pr-merged\/15{background-color:color-mix(in oklab,var(--color-pr-merged) 15%,transparent)}}.bg-surface{background-color:var(--color-surface)}.bg-surface-2{background-color:var(--color-surface-2)}.bg-surface-2\/60{background-color:#1b1e2699}@supports (color:color-mix(in lab,red,red)){.bg-surface-2\/60{background-color:color-mix(in oklab,var(--color-surface-2) 60%,transparent)}}.bg-surface\/40{background-color:#14161b66}@supports (color:color-mix(in lab,red,red)){.bg-surface\/40{background-color:color-mix(in oklab,var(--color-surface) 40%,transparent)}}.bg-surface\/60{background-color:#14161b99}@supports (color:color-mix(in lab,red,red)){.bg-surface\/60{background-color:color-mix(in oklab,var(--color-surface) 60%,transparent)}}.bg-surface\/95{background-color:#14161bf2}@supports (color:color-mix(in lab,red,red)){.bg-surface\/95{background-color:color-mix(in oklab,var(--color-surface) 95%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-working{background-color:var(--color-working)}.bg-working\/10{background-color:#f5a6231a}@supports (color:color-mix(in lab,red,red)){.bg-working\/10{background-color:color-mix(in oklab,var(--color-working) 10%,transparent)}}.bg-working\/15{background-color:#f5a62326}@supports (color:color-mix(in lab,red,red)){.bg-working\/15{background-color:color-mix(in oklab,var(--color-working) 15%,transparent)}}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-px{padding-block:1px}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-1{padding-right:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.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-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--color-accent)}.text-add{color:var(--color-add)}.text-bg{color:var(--color-bg)}.text-black{color:var(--color-black)}.text-del{color:var(--color-del)}.text-del\/80{color:#ff6b6bcc}@supports (color:color-mix(in lab,red,red)){.text-del\/80{color:color-mix(in oklab,var(--color-del) 80%,transparent)}}.text-faint{color:var(--color-faint)}.text-muted{color:var(--color-muted)}.text-pr-merged{color:var(--color-pr-merged)}.text-text{color:var(--color-text)}.text-white{color:var(--color-white)}.text-working{color:var(--color-working)}.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,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.\[color-scheme\:dark\]{color-scheme:dark}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_0_100vmax_rgba\(0\,0\,0\,0\.5\)\]{--tw-shadow:0 0 0 100vmax var(--tw-shadow-color,#00000080);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-black\/40{--tw-shadow-color:#0006}@supports (color:color-mix(in lab,red,red)){.shadow-black\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-black\/60{--tw-shadow-color:#0009}@supports (color:color-mix(in lab,red,red)){.shadow-black\/60{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 60%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-surface{--tw-ring-color:var(--color-surface)}.blur{--tw-blur:blur(8px);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,)}.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{--tw-backdrop-blur:blur(8px);-webkit-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,);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,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-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,);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{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-open\/steps\:invisible:is(:where(.group\/steps):is([open],:popover-open,:open) *){visibility:hidden}.group-open\/steps\:rotate-90:is(:where(.group\/steps):is([open],:popover-open,:open) *),.group-open\/think\:rotate-90:is(:where(.group\/think):is([open],:popover-open,:open) *){rotate:90deg}.placeholder\:font-sans::placeholder{font-family:var(--font-sans)}.placeholder\:text-faint::placeholder{color:var(--color-faint)}@media(hover:hover){.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:-2px}.focus-visible\:outline-accent:focus-visible{outline-color:var(--color-accent)}.active\:scale-90:active{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.985\]:active{scale:.985}.active\:bg-black\/70:active{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.active\:bg-black\/70:active{background-color:color-mix(in oklab,var(--color-black) 70%,transparent)}}.active\:bg-surface:active{background-color:var(--color-surface)}.active\:bg-surface-2:active{background-color:var(--color-surface-2)}.active\:text-text:active{color:var(--color-text)}.active\:opacity-80:active{opacity:.8}.disabled\:bg-surface-2:disabled{background-color:var(--color-surface-2)}.disabled\:text-faint:disabled{color:var(--color-faint)}.disabled\:text-faint\/40:disabled{color:#5c616d66}@supports (color:color-mix(in lab,red,red)){.disabled\:text-faint\/40:disabled{color:color-mix(in oklab,var(--color-faint) 40%,transparent)}}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.has-\[textarea\:focus\]\:border-accent\/60:has(:is(textarea:focus)){border-color:#8b7dff99}@supports (color:color-mix(in lab,red,red)){.has-\[textarea\:focus\]\:border-accent\/60:has(:is(textarea:focus)){border-color:color-mix(in oklab,var(--color-accent) 60%,transparent)}}@media(prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}@media(min-width:48rem){.md\:static{position:static}.md\:inset-0{inset:0}.md\:inset-6{inset:calc(var(--spacing) * 6)}.md\:z-auto{z-index:auto}.md\:m-auto{margin:auto}.md\:mb-6{margin-bottom:calc(var(--spacing) * 6)}.md\:block{display:block}.md\:hidden{display:none}.md\:h-fit{height:fit-content}.md\:w-72{width:calc(var(--spacing) * 72)}.md\:max-w-none{max-width:none}.md\:shrink-0{flex-shrink:0}.md\:translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:rounded-3xl{border-radius:var(--radius-3xl)}.md\:border{border-style:var(--tw-border-style);border-width:1px}.md\:border-border-soft{border-color:var(--color-border-soft)}.md\:transition-none{transition-property:none}}@media(min-width:64rem){.lg\:static{position:static}.lg\:z-auto{z-index:auto}.lg\:w-80{width:calc(var(--spacing) * 80)}.lg\:w-\[380px\]{width:380px}.lg\:shrink-0{flex-shrink:0}.lg\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.lg\:border-border-soft{border-color:var(--color-border-soft)}}@media(min-width:80rem){.xl\:w-\[460px\]{width:460px}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@keyframes typing{0%,60%,to{opacity:.35;transform:none}30%{opacity:1;transform:translateY(-3px)}}@keyframes fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.fade-in{animation:.18s ease-out fade-in}@media(prefers-reduced-motion:reduce){.fade-in{opacity:1;animation:none}.typing-dot{opacity:.6;animation:none}}.pt-safe{padding-top:max(env(safe-area-inset-top),.5rem)}.pb-safe{padding-bottom:max(env(safe-area-inset-bottom),.5rem)}html[data-keyboard] .pb-safe{padding-bottom:.5rem}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
package/dist/index.html CHANGED
@@ -13,8 +13,8 @@
13
13
  <title>Conductor Remote</title>
14
14
  <!-- Runs before the module bundle so it can catch a stale shell that fails to boot. -->
15
15
  <script src="/self-heal.js"></script>
16
- <script type="module" crossorigin src="/assets/index-D3FckDjN.js"></script>
17
- <link rel="stylesheet" crossorigin href="/assets/index-BHetu12h.css">
16
+ <script type="module" crossorigin src="/assets/index-CHhZJBVH.js"></script>
17
+ <link rel="stylesheet" crossorigin href="/assets/index-UopM0hHW.css">
18
18
  <link rel="manifest" href="/manifest.webmanifest"></head>
19
19
  <body>
20
20
  <div id="root"></div>
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const t=e=>i(e,o),c={module:{uri:o},exports:l,require:t};s[o]=Promise.all(n.map(e=>c[e]||t(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"890f6a70e97d144f4d025254e90892a1"},{url:"index.html",revision:"13ed6b91304eca7567c470e6f43e4f2b"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-D3FckDjN.js",revision:null},{url:"assets/index-BHetu12h.css",revision:null},{url:"apple-touch-icon.png",revision:"2b9301416b880d45d4bb655f2600d1f2"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
1
+ if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const t=e=>i(e,o),c={module:{uri:o},exports:l,require:t};s[o]=Promise.all(n.map(e=>c[e]||t(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"890f6a70e97d144f4d025254e90892a1"},{url:"index.html",revision:"79c117a92e7635dd0174f5aeb1f3940c"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-UopM0hHW.css",revision:null},{url:"assets/index-CHhZJBVH.js",revision:null},{url:"apple-touch-icon.png",revision:"2b9301416b880d45d4bb655f2600d1f2"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
@@ -789,6 +789,40 @@ on selectChatTab()
789
789
  end tell
790
790
  end selectChatTab
791
791
 
792
+ on cancelAgent()
793
+ -- Stop the answer this chat is streaming: Conductor's own "Cancel agent"
794
+ -- command, Command-Shift-Delete (key code 51). Taken from its Keyboard
795
+ -- shortcuts dialog (Command-slash, section "Chat"), not guessed - and it is
796
+ -- the only lever there is. The menu bar carries no stop command and neither
797
+ -- does the palette, and the composer's stop BUTTON is unnamed to
798
+ -- Accessibility: no title, no description, no help, no identifier, telling
799
+ -- itself apart from the send button beside it only by its Tailwind classes.
800
+ -- Which is a distinction worth nothing at the moment it matters, because
801
+ -- while a chat is working with a draft in the composer BOTH buttons are on
802
+ -- screen - stop on the left, send on the right - so "press the last button"
803
+ -- steers the running agent with whatever was half-typed instead of stopping
804
+ -- it. A keystroke can't confuse the two.
805
+ --
806
+ -- The keystroke lands wherever focus is, so this asserts the pane first, the
807
+ -- same check a send makes before typing. Cancelling the wrong agent destroys
808
+ -- work that was running fine, which is the same class of damage as landing a
809
+ -- prompt in the wrong chat and gets the same answer: error out, never guess.
810
+ set strips to my tabGroups()
811
+ if (count of strips) is 0 then error "couldn't find the chat pane to cancel in"
812
+ my assertWorkspace(item 1 of strips)
813
+ -- Command-L ("Focus chat input") first, so the shortcut is delivered inside the
814
+ -- chat view rather than to a terminal panel that had focus, where the terminal
815
+ -- would swallow it. It also parks focus somewhere harmless: the composer keeps
816
+ -- its draft, since Conductor binds this chord to Cancel agent rather than to any
817
+ -- text-deletion the field would otherwise do with it.
818
+ tell application "System Events"
819
+ keystroke "l" using {command down}
820
+ delay 0.2
821
+ key code 51 using {command down, shift down}
822
+ end tell
823
+ delay 0.3
824
+ end cancelAgent
825
+
792
826
  on composerControls()
793
827
  set strips to my tabGroups()
794
828
  if (count of strips) is 0 then error "couldn't find the composer"
@@ -1120,3 +1154,158 @@ on setWorkspaceStatus()
1120
1154
  end tell
1121
1155
  delay 0.6
1122
1156
  end setWorkspaceStatus
1157
+
1158
+ (* -- Instant Hotspot ----------------------------------------------------------
1159
+ The funnel watchdog's last resort when this Mac has no route: press the row
1160
+ for a personal hotspot in Control Center's Wi-Fi popover. networksetup can
1161
+ only join a network that is broadcasting, and a personal hotspot usually
1162
+ is not - the row in the Wi-Fi menu is fed by Continuity over Bluetooth, and
1163
+ pressing it asks the phone to wake its hotspot, exactly like a human
1164
+ clicking the Wi-Fi menu. Everything here targets process "ControlCenter",
1165
+ not Conductor - same Accessibility grant, different process, which is why
1166
+ the refusal mapping below skips refusalReason's -1712 branch (its words are
1167
+ about a wedged Conductor).
1168
+ Addressed by AXIdentifier throughout ("com.apple.menuextra.wifi",
1169
+ "wifi-network-<name>", "wifi-header") - the items' names are missing value
1170
+ and any visible text is localized, the identifiers are neither (measured
1171
+ live on macOS 26.5, 2026-08). A "whose value of attribute ..." filter fails
1172
+ wholesale (-1728) when any element lacks the attribute - several menu bar
1173
+ items do - so every lookup here walks with a per-item try instead.
1174
+ The SE-terms trap at the top of CLAUDE.md's applescript section bit this
1175
+ code through a HANDLER PARAMETER: findAxId's first argument was once named
1176
+ `container`, a System Events dictionary word, so inside the tell it
1177
+ resolved as the term and the walk found nothing - through an error-eating
1178
+ try, so a provably open popover read as "no popover" for a whole debugging
1179
+ session while every direct read worked. osacompile accepts it, the handler
1180
+ check can't see it. Keep every identifier in these handlers boring and
1181
+ un-dictionary-like.
1182
+ The menu bar item is a TOGGLE: the same press opens and closes the
1183
+ popover, so nothing here presses it without first checking which state the
1184
+ popover is in (wifiPopoverWindow), and an already-open popover aborts the
1185
+ run - a human may be mid-gesture in it, and their next click kills an
1186
+ automated run anyway (contention looks exactly like the status-row menu's:
1187
+ fails while someone uses the Mac, clean when it is unattended). *)
1188
+
1189
+ on wifiMenuBarItem()
1190
+ try
1191
+ with timeout of 6 seconds
1192
+ tell application "System Events" to tell process "ControlCenter"
1193
+ repeat with mi in menu bar items of menu bar 1
1194
+ try
1195
+ if (value of attribute "AXIdentifier" of mi) is "com.apple.menuextra.wifi" then return contents of mi
1196
+ end try
1197
+ end repeat
1198
+ end tell
1199
+ end timeout
1200
+ on error errText number errNum
1201
+ if errNum is not -1712 then
1202
+ set refusal to my refusalReason({-1, errNum, errText})
1203
+ if refusal is not "" then error refusal
1204
+ end if
1205
+ error "reading the menu bar failed (" & errNum & "): " & errText
1206
+ end try
1207
+ error "the Wi-Fi control is not in the menu bar - turn on Show in Menu Bar for Wi-Fi in System Settings > Control Center"
1208
+ end wifiMenuBarItem
1209
+
1210
+ on findAxId(parentEl, wantedId, depth)
1211
+ -- Depth-capped even though the popover is small: the cap is what keeps a
1212
+ -- macOS reshuffle of this tree from turning one lookup into a full crawl.
1213
+ -- `parentEl` is deliberately not `container` - see the section comment.
1214
+ tell application "System Events"
1215
+ try
1216
+ set kids to UI elements of parentEl
1217
+ on error
1218
+ return missing value
1219
+ end try
1220
+ end tell
1221
+ repeat with el in kids
1222
+ try
1223
+ tell application "System Events"
1224
+ if (value of attribute "AXIdentifier" of el) is wantedId then return contents of el
1225
+ end tell
1226
+ end try
1227
+ if depth > 1 then
1228
+ set hit to my findAxId(el, wantedId, depth - 1)
1229
+ if hit is not missing value then return hit
1230
+ end if
1231
+ end repeat
1232
+ return missing value
1233
+ end findAxId
1234
+
1235
+ on wifiPopoverWindow()
1236
+ -- The popover is whichever ControlCenter window carries the "wifi-header"
1237
+ -- id. Existence is read fresh on every call: pressing a network row can
1238
+ -- close the popover by itself, and the menu bar item is a toggle, so a
1239
+ -- blind second press would reopen what just closed.
1240
+ tell application "System Events" to tell process "ControlCenter"
1241
+ try
1242
+ set wins to windows
1243
+ on error
1244
+ return missing value
1245
+ end try
1246
+ end tell
1247
+ repeat with w in wins
1248
+ if my findAxId(w, "wifi-header", 3) is not missing value then return contents of w
1249
+ end repeat
1250
+ return missing value
1251
+ end wifiPopoverWindow
1252
+
1253
+ on closeWifiPopover(wifiItem)
1254
+ if my wifiPopoverWindow() is not missing value then
1255
+ try
1256
+ tell application "System Events" to perform action "AXPress" of wifiItem
1257
+ end try
1258
+ end if
1259
+ end closeWifiPopover
1260
+
1261
+ on joinInstantHotspot()
1262
+ -- The name arrives via a file, like RELAY_PROMPT_FILE: do shell script
1263
+ -- output is decoded as UTF-8, so a name with non-ASCII letters survives
1264
+ -- where a system attribute read may not. AppleScript's default nonliteral
1265
+ -- text comparison then treats composed and decomposed accents as equal,
1266
+ -- which matters because the AX identifier uses whatever normalization
1267
+ -- macOS chose.
1268
+ set hotspotName to do shell script "cat " & quoted form of (system attribute "RELAY_HOTSPOT_FILE")
1269
+ if hotspotName is "" then error "no hotspot name provided"
1270
+ -- The lock screen hides the session from Accessibility, so behind it this
1271
+ -- press has nothing to land on. Named up front, in the same words the send
1272
+ -- path uses, instead of surfacing later as a popover that never opened.
1273
+ if my screenLocked() is "locked" then error "The Mac is locked - the Wi-Fi menu can't be pressed until it unlocks"
1274
+ set wifiItem to my wifiMenuBarItem()
1275
+ if my wifiPopoverWindow() is not missing value then error "the Wi-Fi popover is already open - someone may be using it, so nothing was pressed"
1276
+ tell application "System Events" to perform action "AXPress" of wifiItem
1277
+ -- The popover renders in its own time (measured 1-2s), and a human's click
1278
+ -- anywhere on the Mac closes it, so poll rather than sleep once.
1279
+ set pop to missing value
1280
+ repeat 8 times
1281
+ delay 0.5
1282
+ set pop to my wifiPopoverWindow()
1283
+ if pop is not missing value then exit repeat
1284
+ end repeat
1285
+ if pop is missing value then error "pressing the Wi-Fi control opened no popover - someone clicking on the Mac closes it the moment it opens (contention, not a fault); otherwise Control Center is not answering"
1286
+ set rowEl to missing value
1287
+ repeat 4 times
1288
+ set rowEl to my findAxId(pop, "wifi-network-" & hotspotName, 6)
1289
+ if rowEl is not missing value then exit repeat
1290
+ delay 0.5
1291
+ end repeat
1292
+ if rowEl is missing value then
1293
+ my closeWifiPopover(wifiItem)
1294
+ error quote & hotspotName & quote & " is not in the Wi-Fi menu - the iPhone is out of Bluetooth range, has Bluetooth off, or Personal Hotspot is off in its Settings"
1295
+ end if
1296
+ -- The row is a toggle too: value 1 means already connected, and pressing
1297
+ -- it then would DISCONNECT - the one outcome worse than doing nothing.
1298
+ -- Only a read of exactly 1 skips the press; an unreadable value presses.
1299
+ set rowValue to 0
1300
+ try
1301
+ tell application "System Events" to set rowValue to value of rowEl
1302
+ end try
1303
+ if rowValue is 1 then
1304
+ my closeWifiPopover(wifiItem)
1305
+ return "already-connected"
1306
+ end if
1307
+ tell application "System Events" to perform action "AXPress" of rowEl
1308
+ delay 1
1309
+ my closeWifiPopover(wifiItem)
1310
+ return "pressed"
1311
+ end joinInstantHotspot
@@ -31,6 +31,7 @@ import { promisify } from 'node:util';
31
31
  import { readSettings } from "./settings.js";
32
32
  import { magicDnsName, readExposeMode, relayPort, tailscaleBin } from "./tailscale.js";
33
33
  import { hasDefaultRoute, joinNetwork, preferredNetworks } from "./wifi.js";
34
+ import { joinInstantHotspot } from "./writes.js";
34
35
  const execFileP = promisify(execFile);
35
36
  const PROBE_PATH = '/health'; // unauthenticated 200 on the relay — no token needed to prove reachability
36
37
  const PROBE_TIMEOUT_MS = 8000;
@@ -157,6 +158,19 @@ let lastHealAt = 0;
157
158
  let lastRejoinAt = 0;
158
159
  const REJOIN_COOLDOWN_MS = 5 * 60 * 1000; // a network switch is disruptive; never churn on one
159
160
  const REJOIN_SETTLE_MS = 12 * 1000; // DHCP + tailscaled noticing the new endpoint
161
+ // An Instant Hotspot press has the phone's Bluetooth wake + hotspot spin-up in front of the
162
+ // same DHCP wait, so it gets a longer leash than a plain join before the tick gives up on it.
163
+ const HOTSPOT_SETTLE_MS = 30 * 1000;
164
+ /** Poll for the default route instead of one fixed sleep — a join that lands early returns early. */
165
+ async function routeAppeared(waitMs) {
166
+ const until = Date.now() + waitMs;
167
+ while (Date.now() < until) {
168
+ if (await hasDefaultRoute())
169
+ return true;
170
+ await new Promise(r => setTimeout(r, 3000));
171
+ }
172
+ return hasDefaultRoute();
173
+ }
160
174
  /**
161
175
  * Last resort when the probe is down: this Mac has no link at all, so move it onto a
162
176
  * configured fallback (your phone's hotspot) and re-register Funnel, whose ingress a
@@ -173,6 +187,14 @@ const REJOIN_SETTLE_MS = 12 * 1000; // DHCP + tailscaled noticing the new endpoi
173
187
  * or passed; an SSID that isn't in the preferred list is named in the log, not tried.
174
188
  * - Behind a cooldown, so a Mac that is simply off the air doesn't cycle its Wi-Fi.
175
189
  *
190
+ * Two ways in, tried in order. `networksetup` first — cheap, no UI — and when it answers
191
+ * "Could not find network" (a hotspot doesn't broadcast until asked), the Accessibility
192
+ * press on the Wi-Fi menu's own row (`joinInstantHotspot` in writes.ts), which wakes the
193
+ * phone's hotspot over Continuity exactly like clicking it. The press needs an unlocked
194
+ * screen — the lock hides the session from Accessibility, and the failure names that —
195
+ * so a lid-closed Mac still wants macOS's own Auto-Join Hotspot set to Automatic as the
196
+ * layer below this one.
197
+ *
176
198
  * Returns true if a join reported success, meaning the caller should re-register rather
177
199
  * than treat this tick as an ordinary failure.
178
200
  */
@@ -194,17 +216,30 @@ async function tryRejoin() {
194
216
  lastRejoinAt = Date.now();
195
217
  for (const ssid of candidates) {
196
218
  log(`no default route — joining fallback network "${ssid}"`);
219
+ let settleMs = REJOIN_SETTLE_MS;
197
220
  const joined = await joinNetwork(ssid);
198
221
  if (!joined.ok) {
199
222
  log(`join "${ssid}" failed: ${joined.error}`);
200
- continue;
223
+ // networksetup can only join a network that is broadcasting, and a personal
224
+ // hotspot usually isn't — its row in the Wi-Fi menu arrives over Continuity,
225
+ // and pressing it wakes the hotspot the way clicking it by hand does. Tried
226
+ // for every failed candidate rather than only hotspot-looking names: the
227
+ // name heuristic never decides anything (see looksLikeHotspot), and for an
228
+ // ordinary network that's simply out of range the press fails in words
229
+ // ("not in the Wi-Fi menu") that cost one popover flash.
230
+ log(`pressing the Wi-Fi menu's "${ssid}" row instead (Instant Hotspot)`);
231
+ const pressed = await joinInstantHotspot(ssid);
232
+ if (!pressed.ok) {
233
+ log(`Instant Hotspot press for "${ssid}" failed: ${pressed.error}`);
234
+ continue;
235
+ }
236
+ settleMs = HOTSPOT_SETTLE_MS;
201
237
  }
202
- await new Promise(r => setTimeout(r, REJOIN_SETTLE_MS));
203
- if (await hasDefaultRoute()) {
238
+ if (await routeAppeared(settleMs)) {
204
239
  log(`joined "${ssid}" and the link is up`);
205
240
  return true;
206
241
  }
207
- log(`joined "${ssid}" but no default route appeared after ${REJOIN_SETTLE_MS / 1000}s`);
242
+ log(`joined "${ssid}" but no default route appeared after ${settleMs / 1000}s`);
208
243
  }
209
244
  return false;
210
245
  }
@@ -19,7 +19,7 @@ import { Reads } from "./reads.js";
19
19
  import { readSettings, writeSettings } from "./settings.js";
20
20
  import { driftWarningLines, tailscaleBin } from "./tailscale.js";
21
21
  import { autoJoinHotspotMode, currentSsid, looksLikeHotspot, preferredNetworks } from "./wifi.js";
22
- import { createWorkspace, describeActuator, EFFORT_LABELS, listAgentModels, lockBlocked, newChat, pickActuator, retryWontHelp, screenLocked, setAgentOptions, setRestartGuard, setWorkspaceStatus, WORKSPACE_STATUS_LABELS } from "./writes.js";
22
+ import { createWorkspace, describeActuator, EFFORT_LABELS, listAgentModels, lockBlocked, newChat, pickActuator, retryWontHelp, screenLocked, setAgentOptions, setRestartGuard, setWorkspaceStatus, stopTurn, WORKSPACE_STATUS_LABELS } from "./writes.js";
23
23
  // Before anything that logs: from here on every console line is also kept in memory for
24
24
  // `GET /api/logs`, so the phone can read why a send failed without ssh-ing into the Mac.
25
25
  installLogCapture();
@@ -737,6 +737,52 @@ const server = http.createServer(async (req, res) => {
737
737
  return json(req, res, 502, { ok: false, strategy: actuator.name, error: applied.error });
738
738
  return json(req, res, 200, { ok: true, session: reads.listSessions(ws.id).find(s => s.id === sessionId) });
739
739
  }
740
+ // POST /api/sessions/:id/stop — the desktop app's stop button, for one chat.
741
+ m = pathname.match(/^\/api\/sessions\/([^/]+)\/stop$/);
742
+ if (req.method === 'POST' && m) {
743
+ const sessionId = decodeURIComponent(m[1]);
744
+ const body = JSON.parse((await readBody(req)) || '{}');
745
+ const ws = body.workspaceId
746
+ ? reads.getWorkspace(body.workspaceId)
747
+ : (reads.listWorkspaces().find(w => w.active_session_id === sessionId) ?? null);
748
+ if (!ws)
749
+ return json(req, res, 404, { error: 'workspace for session not found' });
750
+ const located = locateChat(ws, sessionId);
751
+ if ('error' in located)
752
+ return json(req, res, 409, { error: located.error });
753
+ // Nothing running is a success, not an error: the phone shows Stop the moment it
754
+ // sends (the optimistic hint) and a turn that ends on its own a beat before the tap
755
+ // is the common case, not a mistake worth a red banner. It also keeps the one
756
+ // keystroke this route presses off an idle chat entirely — Conductor's own
757
+ // composer has no stop button to mis-tap there either.
758
+ const before = reads.listSessions(ws.id).find(s => s.id === sessionId);
759
+ if (before?.status !== 'working') {
760
+ return json(req, res, 200, { ok: true, alreadyIdle: true, session: before });
761
+ }
762
+ const result = await stopTurn({ workspace: ws, sessionId, tab: located.tab });
763
+ if (!result.ok)
764
+ return json(req, res, 502, result);
765
+ // The DB is the receipt, exactly as it is for agent settings: the keystroke is
766
+ // fire-and-forget, so what counts is `status` leaving `working`. Conductor writes
767
+ // that a beat after it tears the turn down.
768
+ let observed = before.status;
769
+ for (let i = 0; i < 20 && observed === 'working'; i++) {
770
+ await sleep(300);
771
+ observed = reads.listSessions(ws.id).find(s => s.id === sessionId)?.status ?? observed;
772
+ }
773
+ if (observed === 'working') {
774
+ return json(req, res, 502, {
775
+ ok: false,
776
+ strategy: result.strategy,
777
+ error: 'Conductor took the stop but the agent is still working. Try again, or stop it on your Mac.'
778
+ });
779
+ }
780
+ return json(req, res, 200, {
781
+ ok: true,
782
+ strategy: result.strategy,
783
+ session: reads.listSessions(ws.id).find(s => s.id === sessionId)
784
+ });
785
+ }
740
786
  // POST /api/sessions/:id/prompt { text, agent? } — agent is the phone's staged
741
787
  // settings patch, applied before the prompt so the two can't come apart (and so
742
788
  // both park together when the Mac turns out to be locked).
@@ -65,6 +65,17 @@ export function parseMessage(row, worktree = null) {
65
65
  // Bookkeeping frames: hooks, init, token accounting, end-of-turn results.
66
66
  if (parsed.type === 'system' || parsed.type === 'result')
67
67
  return [];
68
+ // How a stopped turn ends: `{"type":"error","content":"aborted by user"}`, and it
69
+ // carries no `message.content`, so without this it fell through to the raw-JSON
70
+ // dump below. That was tolerable while stopping needed a Mac; the phone can do it
71
+ // now (`POST /api/sessions/:id/stop`), so it is the last line of every stopped
72
+ // chat. The SDK's own wording is kept rather than reworded — "aborted by user" is
73
+ // already plain, and inventing a phrase here would drift from what the desktop shows.
74
+ if (parsed.type === 'error') {
75
+ const said = str(parsed.content);
76
+ if (said)
77
+ return [{ ...base, id: row.id, role: 'system', text: clip(said, 200) }];
78
+ }
68
79
  const blocks = parsed.message?.content;
69
80
  if (!Array.isArray(blocks)) {
70
81
  if (parsed.type === 'user' || parsed.type === 'assistant')
@@ -261,12 +261,12 @@ function targetEnv(target) {
261
261
  };
262
262
  }
263
263
  /** osascript echoes the whole failing script back; keep just the reason for the phone. */
264
- function osaError(err) {
264
+ function osaError(err, timeoutMsg = 'Conductor took too long to respond') {
265
265
  const raw = err instanceof Error ? err.message : String(err);
266
266
  // A timeout kill carries no execution error at all — its first line is
267
267
  // "Command failed: osascript -e" plus the whole script, which is useless here.
268
268
  if (err && typeof err === 'object' && 'killed' in err && err.killed) {
269
- return 'Conductor took too long to respond';
269
+ return timeoutMsg;
270
270
  }
271
271
  return raw.match(/execution error: (.+?) \(-?\d+\)/)?.[1] ?? raw.split('\n')[0];
272
272
  }
@@ -330,6 +330,86 @@ end tell
330
330
  }
331
331
  }
332
332
  }
333
+ /**
334
+ * Stop the answer a chat is streaming — the desktop app's stop button, reached
335
+ * through the same focus-and-assert path as a send and then Conductor's own
336
+ * "Cancel agent" shortcut (see `cancelAgent` in conductor.applescript for why a
337
+ * keystroke rather than the button).
338
+ *
339
+ * The branch is required rather than optional. Everywhere else a workspace with
340
+ * no branch merely loses the pane assertion; here that assertion is the only thing
341
+ * standing between "stop this agent" and "throw away a different agent's turn", so
342
+ * a target that can't be checked is refused instead of aimed.
343
+ *
344
+ * Nothing is confirmed here: `sessions.status` leaving `working` is the receipt and
345
+ * server.ts waits for it, the same way agent settings are confirmed against the DB
346
+ * rather than against the UI that was just driven.
347
+ */
348
+ export async function stopTurn(target) {
349
+ if (!target.workspace.branch) {
350
+ return { ok: false, strategy: 'applescript', error: 'workspace has no branch to focus' };
351
+ }
352
+ const script = `
353
+ ${CONDUCTOR_HANDLERS}
354
+
355
+ my activateConductor()
356
+ my focusWorkspace()
357
+ my selectChatTab()
358
+ my cancelAgent()
359
+ return "ok"`.trim();
360
+ try {
361
+ await uiTurn(() => exec('osascript', ['-e', script], {
362
+ env: { ...process.env, ...targetEnv(target) },
363
+ timeout: SEND_ATTEMPT_MS
364
+ }));
365
+ return { ok: true, strategy: 'applescript' };
366
+ }
367
+ catch (err) {
368
+ return { ok: false, strategy: 'applescript', error: osaError(err) };
369
+ }
370
+ }
371
+ /**
372
+ * Press the Wi-Fi menu's row for a personal hotspot — Instant Hotspot, the same
373
+ * button a human clicks. `networksetup` can only join a network that is
374
+ * broadcasting, and a personal hotspot usually isn't; the row in Control
375
+ * Center's Wi-Fi popover is fed by Continuity over Bluetooth, and pressing it
376
+ * asks the phone to wake its hotspot. The funnel watchdog reaches for this when
377
+ * a plain join answered "Could not find network".
378
+ *
379
+ * The one UI write here that doesn't target Conductor, and it still takes a
380
+ * uiTurn: the popover steals key focus, so a palette fallback running at the
381
+ * same moment would type into it. The name travels via a temp file like the
382
+ * prompt does — same escaping-and-encoding dodge, and hotspot names ("Han
383
+ * høyes iPhone") are non-ASCII more often than prompts are. Success here means
384
+ * *pressed*, nothing more: joining takes several seconds of Bluetooth wake +
385
+ * DHCP, so the caller owns the wait, and it watches `hasDefaultRoute()` — the
386
+ * one link signal that needs no permission — not this function's word.
387
+ * Everything else — the lock check, the toggle-aware close, the already-open
388
+ * abort, the contention story — lives with the handler in conductor.applescript.
389
+ */
390
+ export async function joinInstantHotspot(name) {
391
+ const script = `
392
+ ${CONDUCTOR_HANDLERS}
393
+
394
+ my joinInstantHotspot()`.trim();
395
+ const os = await import('node:os');
396
+ const fs = await import('node:fs/promises');
397
+ const tmp = path.join(os.tmpdir(), `relay-hotspot-${process.pid}-${Date.now()}.txt`);
398
+ await fs.writeFile(tmp, name, 'utf8');
399
+ try {
400
+ await uiTurn(() => exec('osascript', ['-e', script], {
401
+ env: { ...process.env, RELAY_HOTSPOT_FILE: tmp },
402
+ timeout: 25_000
403
+ }));
404
+ return { ok: true };
405
+ }
406
+ catch (err) {
407
+ return { ok: false, error: osaError(err, 'the Wi-Fi menu press took too long') };
408
+ }
409
+ finally {
410
+ await fs.rm(tmp, { force: true }).catch(() => undefined);
411
+ }
412
+ }
333
413
  /**
334
414
  * Conductor stores the effort level as `sessions.claude_effort_level`, but the
335
415
  * composer button is labelled with the human name and *cycles* through them in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-remote",
3
- "version": "1.37.0",
3
+ "version": "1.39.0",
4
4
  "type": "module",
5
5
  "packageManager": "yarn@4.15.0",
6
6
  "description": "Phone control panel for local Conductor agents. Reads ride SQLite + git; prompts ride Conductor's own dispatch path.",