@augmentcode/onison 0.0.1 → 0.0.21

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,24 @@
1
+ // @bun
2
+ import{Container as F7,Text as jJ}from"@earendil-works/pi-tui";import{getKeybindings as mz}from"@earendil-works/pi-tui";import{getMarkdownTheme as Hz}from"@augmentcode/auggie-v2";import{Input as y$}from"@earendil-works/pi-tui";function b(J){return{apply:($,z)=>J.component.setProps(J.select($,z)),invalidate:()=>J.component.invalidate()}}function c(J){return{apply:($,z)=>{if(J.predicate&&!J.predicate($,z))return;J.resolve(z.tab)?.setProps(J.select($,z))}}}import{visibleWidth as UJ,wrapTextWithAnsi as QJ}from"@earendil-works/pi-tui";var x=" (Recommended)",pJ=UJ(x);class H{static ACTIVE_POINTER="\u276F ";static INACTIVE_POINTER=" ";static NUMBER_SEPARATOR=". ";static INPUT_CURSOR_START="\x1B[7m";static INPUT_CURSOR_END="\x1B[27m";static SEGMENTER=new Intl.Segmenter;static CONFIRMED_MARK=" \u2714";static MIN_CONTENT_WIDTH=1;items;maxVisible;theme;numberStartOffset;totalItemsForNumbering;selectedIndex=0;focused=!0;inputBuffer="";inputCursor=0;confirmedIndex=void 0;confirmedLabelOverride=void 0;constructor(J,$,z,Z={}){this.items=J,this.maxVisible=Math.max(1,$),this.theme=z,this.numberStartOffset=Z.numberStartOffset??0,this.totalItemsForNumbering=Z.totalItemsForNumbering??J.length}setNumbering(J,$){this.numberStartOffset=J,this.totalItemsForNumbering=Math.max(1,$)}setSelectedIndex(J){this.selectedIndex=Math.max(0,Math.min(J,this.items.length-1))}setFocused(J){this.focused=J}setConfirmedIndex(J,$){if(J===void 0){this.confirmedIndex=void 0,this.confirmedLabelOverride=void 0;return}this.confirmedIndex=Math.max(0,Math.min(J,this.items.length-1)),this.confirmedLabelOverride=$}setInputBuffer(J){if(this.inputBuffer=J,this.inputCursor>J.length)this.inputCursor=J.length}setInputCursor(J){this.inputCursor=Math.max(0,Math.min(J,this.inputBuffer.length))}handleInput(J){}invalidate(){}render(J){if(this.items.length===0)return[];let{startIndex:$,endIndex:z}=this.computeVisibleWindow(),Z=String(Math.max(1,this.totalItemsForNumbering)).length,Y=[];for(let G=$;G<z;G++){let X=this.items[G];if(!X)continue;let j=G===this.selectedIndex&&this.focused;Y.push(...this.renderItem(X,G,j,J,Z))}if(this.hasItemsOutsideWindow($,z))Y.push(this.theme.scrollInfo(` (${this.selectedIndex+1}/${this.items.length})`));return Y}computeVisibleWindow(){let J=Math.floor(this.maxVisible/2),$=Math.max(0,Math.min(this.selectedIndex-J,this.items.length-this.maxVisible)),z=Math.min($+this.maxVisible,this.items.length);return{startIndex:$,endIndex:z}}hasItemsOutsideWindow(J,$){return J>0||$<this.items.length}renderItem(J,$,z,Z,Y){let G=this.buildRowPrefix($,z,Y),X=" ".repeat(UJ(G)),j=Math.max(H.MIN_CONTENT_WIDTH,Z-UJ(G));if(this.shouldRenderAsInlineInput(J,z))return this.renderInlineInputRow(G,X,j);let K=$===this.confirmedIndex,Q=J.kind==="option"&&J.recommended===!0?x:"",V=K?this.confirmedLabelOverride??`${J.label}${Q}`:`${J.label}${Q}`,F=K?`${V}${H.CONFIRMED_MARK}`:V,B=z||K;return[...this.renderLabelBlock(F,G,X,j,B),...this.renderDescriptionBlock(J.description,X,j)]}buildRowPrefix(J,$,z){let Z=$?H.ACTIVE_POINTER:H.INACTIVE_POINTER,Y=this.numberStartOffset+J+1,G=String(Y).padStart(z," ");return`${Z}${G}${H.NUMBER_SEPARATOR}`}shouldRenderAsInlineInput(J,$){return J.kind==="other"&&$}renderInlineInputRow(J,$,z){let Z=Math.max(0,Math.min(this.inputCursor,this.inputBuffer.length)),Y=this.inputBuffer.slice(0,Z),G=this.inputBuffer.slice(Z),j=H.SEGMENTER.segment(G)[Symbol.iterator]().next().value?.segment??" ",K=G.slice(j.length),Q=`${Y}${H.INPUT_CURSOR_START}${j}${H.INPUT_CURSOR_END}${K}`;return QJ(Q,z).map((F,B)=>{let D=B===0?J:$;return this.theme.selectedText(`${D}${F}`)})}renderLabelBlock(J,$,z,Z,Y){return QJ(J,Z).map((X,j)=>{let Q=`${j===0?$:z}${X}`;return Y?this.theme.selectedText(Q):Q})}renderDescriptionBlock(J,$,z){if(!J)return[];return QJ(J,z).map((Y)=>`${$}${this.theme.description(Y)}`)}}class VJ{select;constructor(J){this.select=new H([J.item],1,J.theme,{numberStartOffset:0,totalItemsForNumbering:1})}setProps(J){this.select.setFocused(J.focused),this.select.setNumbering(J.numbering.offset,J.numbering.total)}handleInput(J){}invalidate(){this.select.invalidate()}render(J){return this.select.render(J)}}import{truncateToWidth as d,visibleWidth as FJ,wrapTextWithAnsi as cJ}from"@earendil-works/pi-tui";var lJ=["other","chat","next"],U={option:{label:"",reserved:!1,livesInMainList:!0,numbered:!0,activatesInputMode:!1,blocksMultiToggle:!1,autoSubmitsInMulti:!1,autoAppendOnSingleSelectNoPreview:!1,autoAppendOnMultiSelect:!1},other:{label:"Type something.",reserved:!0,livesInMainList:!0,numbered:!0,activatesInputMode:!0,blocksMultiToggle:!1,autoSubmitsInMulti:!1,autoAppendOnSingleSelectNoPreview:!0,autoAppendOnMultiSelect:!1},chat:{label:"Chat about this",reserved:!0,livesInMainList:!1,numbered:!0,activatesInputMode:!1,blocksMultiToggle:!1,autoSubmitsInMulti:!1,autoAppendOnSingleSelectNoPreview:!1,autoAppendOnMultiSelect:!1},next:{label:"Next",reserved:!0,livesInMainList:!0,numbered:!1,activatesInputMode:!1,blocksMultiToggle:!0,autoSubmitsInMulti:!0,autoAppendOnSingleSelectNoPreview:!1,autoAppendOnMultiSelect:!0}},m$={other:U.other.label,chat:U.chat.label,next:U.next.label},O7=new Set(["Other",...lJ.filter((J)=>U[J].reserved).map((J)=>U[J].label)]);function uJ(J,$){let z=[];for(let Z of lJ){let Y=U[Z];if(!Y.livesInMainList)continue;if(J.multiSelect===!0){if(Y.autoAppendOnMultiSelect)z.push(Z)}else if(Y.autoAppendOnSingleSelectNoPreview&&!$)z.push(Z)}return z}var dJ="\u276F ",kJ=" ",h$="[\u2714]",oJ="[ ]",rJ=". ",nJ=" ",p$=" ",sJ="Submit";class BJ{props;theme;question;constructor(J,$){this.theme=J,this.question=$,this.props={rows:[],nextActive:!1,nextLabel:U.next.label}}setProps(J){this.props=J}handleInput(J){}invalidate(){}render(J){let $=[],z=this.prefixVisibleWidth(),Z=Math.max(1,J-z),Y=String(Math.max(1,this.question.options.length)).length;for(let j=0;j<this.question.options.length;j++){let K=this.question.options[j],Q=this.props.rows[j];if(!K||!Q)continue;let V=Q.active?this.theme.fg("accent",dJ):kJ,F=Q.checked?this.theme.fg("accent",h$):this.theme.fg("muted",oJ),B=K.recommended===!0?`${d(K.label,Math.max(1,Z-FJ(x)),"\u2026")}${x}`:d(K.label,Z,"\u2026"),D=Q.active?this.theme.fg("accent",this.theme.bold(B)):B,L=String(j+1).padStart(Y," "),u=`${V}${L}${rJ}${F}${nJ}${D}`;if($.push(d(u,J,"")),K.description){let _=cJ(K.description,Z);for(let KJ of _)$.push(p$+this.theme.fg("muted",KJ))}}let G=this.props.nextActive?this.theme.fg("accent",dJ):kJ,X=this.props.nextActive?this.theme.fg("accent",this.theme.bold(this.props.nextLabel)):this.props.nextLabel;return $.push(d(`${G}${X}`,J,"")),$}naturalHeight(J){let $=Math.max(1,J-this.prefixVisibleWidth()),z=0;for(let Z of this.question.options){if(!Z)continue;if(z+=1,Z.description)z+=cJ(Z.description,$).length}return z+1}prefixVisibleWidth(){let J=String(Math.max(1,this.question.options.length)).length;return FJ(kJ)+J+FJ(`${rJ}${oJ}${nJ}`)}}var l$=10;class HJ{select;constructor(J){this.select=new H(J.items,Math.min(J.items.length,l$),J.theme,{numberStartOffset:0,totalItemsForNumbering:J.items.length+1})}setProps(J){this.select.setSelectedIndex(J.selectedIndex),this.select.setFocused(J.focused),this.select.setConfirmedIndex(J.confirmed?.index,J.confirmed?.labelOverride),this.select.setInputBuffer(J.inputBuffer),this.select.setInputCursor(J.inputCursor)}handleInput(J){}invalidate(){this.select.invalidate()}render(J){return this.select.render(J)}}import{Markdown as n$,visibleWidth as s$}from"@earendil-works/pi-tui";import{truncateToWidth as u$,visibleWidth as c$}from"@earendil-works/pi-tui";var d$=new RegExp("\\x1b\\[[0-9;]*m","g"),o$=new RegExp("\\x1b\\]8;[^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)","g"),r$=/^`{3}/,T=2,P=2,M=1,aJ=40;function CJ(J){return J.filter(($)=>{let z=$.replace(d$,"").replace(o$,"");return!r$.test(z)})}function MJ(J,$,z,Z=0){let Y=Math.max(1,$-P),G=Math.max(1,Y-2*M),X=" ".repeat(M),K=[z(`\u250C${"\u2500".repeat(Y)}\u2510`)];for(let Q of J){let V=u$(Q,G,"",!0);K.push(`${z("\u2502")}${X}${V}${X}${z("\u2502")}`)}if(Z>0){let Q=` \u2702 \u2500\u2500 ${Z} lines hidden \u2500\u2500 `,V=Y-Q.length,F="\u2500".repeat(Math.max(0,Math.floor(V/2))),B="\u2500".repeat(Math.max(0,Y-F.length-Q.length));K.push(z(`\u2514${F}${Q}${B}\u2518`))}else K.push(z(`\u2514${"\u2500".repeat(Y)}\u2518`));return K}function iJ(J,$){let z=Math.min(aJ,$);for(let G of J){let X=c$(G.replace(/\s+$/,""));if(X>z)z=X}let Z=Math.min(z,$),Y=Z+P+2*M;return{innerWidth:Z,boxWidth:Y}}var o=20,r=15,eJ="No preview available",E=2;class yJ{previewTexts;markdownCache;cachedWidth;theme;markdownTheme;constructor(J,$,z){this.theme=$,this.markdownTheme=z,this.previewTexts=new Map;for(let Z=0;Z<J.options.length;Z++){let Y=J.options[Z]?.preview;if(Y&&Y.length>0)this.previewTexts.set(Z,Y)}this.markdownCache=new Map}hasAnyPreview(){return this.previewTexts.size>0}has(J){return this.previewTexts.has(J)}bodyFor(J,$){if(this.cachedWidth!==$){for(let Y of this.markdownCache.values())Y.invalidate();this.cachedWidth=$}let z=this.previewTexts.get(J);if(!z){let Y=this.theme.fg("dim",eJ),G=Math.max(0,$-s$(Y));return[Y+" ".repeat(G)]}let Z=this.markdownCache.get(J);if(!Z)Z=new n$(z,0,0,this.markdownTheme),this.markdownCache.set(J,Z);return CJ(Z.render($))}invalidate(){for(let J of this.markdownCache.values())J.invalidate();this.cachedWidth=void 0}}var tJ="Notes: press n to add notes";class n{theme;cache;constructor(J){this.theme=J.theme,this.cache=new yJ(J.question,J.theme,J.markdownTheme)}hasAnyPreview(){return this.cache.hasAnyPreview()}has(J){return this.cache.has(J)}invalidate(){this.cache.invalidate()}blockHeight(J,$,z){let Y=Math.max(1,(z==="side-by-side"?o:r)-T-E),G=Math.max(1,J-P-2*M),X=this.cache.bodyFor($,G).length,j=Math.min(X,Y);return T+j+E}renderBlock(J,$,z,Z,Y){let X=Math.max(1,(z==="side-by-side"?o:r)-T-E),j=Math.max(1,J-P-2*M),K=this.cache.bodyFor($,j),Q=K.length>X,V=Q?K.length-X:0,F=Q?K.slice(0,X):K,{boxWidth:B}=iJ(F,j),L=MJ(F,B,(KJ)=>this.theme.fg("accent",KJ),V),_=Z&&!Y&&this.cache.has($)?this.theme.fg("muted",tJ):"";return[...L,"",_]}}import{visibleWidth as J$}from"@earendil-works/pi-tui";var qJ=100,O=2,R=1,w=1,s=30,a$=0.5,DJ=45,i$=2;function a(J,$){return J>=qJ&&$>=qJ?"side-by-side":"stacked"}function e$(J,$,z){let Z=String(Math.max(1,$)).length+4,Y=i$,G=0;for(let Q of J){let V=Q.kind==="option"&&Q.recommended===!0?pJ:0,F=J$(Q.label)+V;if(F>G)G=F}let X=G+Z+Y,j=Math.min(X,Math.floor(z*a$)),K=z-O-DJ;return Math.max(s,Math.min(j,Math.max(1,K)))}function t$(J,$,z){let Z=s;for(let Y=0;Y<J.length;Y++){let G=$[Y]??[],X=J[Y]?.multiSelect?G.length:G.length+1,j=e$(G,X,z);if(j>Z)Z=j}return Z}function Jz(J){let $=0;for(let z of J.options){let Z=z.preview;if(!Z)continue;for(let Y of Z.split(`
3
+ `)){let G=J$(Y);if(G>$)$=G}}return $}function $z(J,$){let z=DJ;for(let Z of J){let Y=Jz(Z),X=Math.min(Y,$-O-s)+P+2*M+R;if(X>z)z=X}return z}function $$(J,$,z,Z){let Y=t$(J,$,Z);if(Y<=s)return Y;let G=$z(z,Z),X=Z-O-G,j=Z-O-DJ;return Math.min(Math.max(Y,X),Math.max(1,j))}function PJ(J,$){let z=O,Z=Math.min($,Math.max(1,J-z-1)),Y=Math.max(1,J-Z-z);return{leftWidth:Z,rightWidth:Y,gap:z}}function LJ(J,$,z){if($==="stacked")return{optionsWidth:J,previewWidth:J};let{leftWidth:Z,rightWidth:Y}=PJ(J,z);return{optionsWidth:Z,previewWidth:Math.max(1,Y-R)}}import{truncateToWidth as z$,visibleWidth as zz}from"@earendil-works/pi-tui";class SJ{question;getTerminalWidth;optionListView;previewBlock;props;globalLeftWidth=()=>{throw Error("PreviewPane.setGlobalLeftWidth must be called before render()")};constructor(J){this.question=J.question,this.getTerminalWidth=J.getTerminalWidth,this.optionListView=J.optionListView,this.previewBlock=J.previewBlock,this.props={notesVisible:!1,selectedIndex:0,focused:!1}}setGlobalLeftWidth(J){this.globalLeftWidth=J}getAdaptiveLeft(J){return this.globalLeftWidth(J)}setProps(J){this.props=J}handleInput(J){}invalidate(){this.previewBlock.invalidate(),this.optionListView.invalidate()}render(J){if(this.question.multiSelect===!0)return this.optionListView.render(J);if(!this.previewBlock.hasAnyPreview())return this.optionListView.render(J);let $=a(this.getTerminalWidth(),J);if($==="side-by-side")return this.renderSideBySide(J,$);return[...this.optionListView.render(J),...Array(w).fill(""),...this.previewBlock.renderBlock(J,this.props.selectedIndex,$,this.props.focused,this.props.notesVisible)]}naturalHeight(J){if(this.question.multiSelect===!0)return this.optionListView.render(J).length;if(!this.previewBlock.hasAnyPreview())return this.optionListView.render(J).length;let $=a(this.getTerminalWidth(),J),z=this.getAdaptiveLeft(J),{optionsWidth:Z,previewWidth:Y}=LJ(J,$,z),G=this.optionListView.render(Z).length,X=this.previewBlock.blockHeight(Y,this.props.selectedIndex,$);if($==="side-by-side")return Math.max(G,X);return G+w+X}maxNaturalHeight(J){if(this.question.multiSelect===!0)return this.optionListView.render(J).length;if(!this.previewBlock.hasAnyPreview())return this.optionListView.render(J).length;let $=a(this.getTerminalWidth(),J),z=this.getAdaptiveLeft(J),{optionsWidth:Z,previewWidth:Y}=LJ(J,$,z),G=this.optionListView.render(Z).length,X=0;for(let j=0;j<this.question.options.length;j++){let K=this.previewBlock.blockHeight(Y,j,$);if(K>X)X=K}if($==="side-by-side")return Math.max(G,X);return G+w+X}renderSideBySide(J,$){let z=this.getAdaptiveLeft(J),{leftWidth:Z,rightWidth:Y,gap:G}=PJ(J,z),X=this.optionListView.render(Z),j=this.renderPaddedPreviewLines(Y,$),K=Math.max(X.length,j.length),Q=" ".repeat(G),V=[];for(let F=0;F<K;F++){let B=X[F]??"",D=j[F]??"",L=z$(B,Z,""),u=" ".repeat(Math.max(0,Z-zz(L))),_=`${L}${u}${Q}${D}`;V.push(z$(_,J,""))}return V}renderPaddedPreviewLines(J,$){let z=Math.max(1,J-R),Z=this.previewBlock.renderBlock(z,this.props.selectedIndex,$,this.props.focused,this.props.notesVisible),Y=" ".repeat(R);return Z.map((G)=>G===""?"":`${Y}${G}`)}}import{truncateToWidth as Zz}from"@earendil-works/pi-tui";var Yz="\u276F ",Gz=" ",Xz=". ",jz="Submit answers",Kz="Cancel";class vJ{props;theme;constructor(J){this.theme=J,this.props={rows:[{active:!1},{active:!1}]}}setProps(J){this.props=J}handleInput(J){}invalidate(){}naturalHeight(J){return 2}render(J){let $=[];for(let z=0;z<2;z++){let Z=z===0?jz:Kz,Y=this.props.rows[z]?.active??!1,G=Y?Yz:Gz,X=`${z+1}${Xz}`,j=Y?this.theme.fg("accent",this.theme.bold(Z)):this.theme.fg("text",Z);$.push(Zz(`${G}${X}${j}`,J,""))}return $}}import{truncateToWidth as Qz}from"@earendil-works/pi-tui";class WJ{props;theme;constructor(J){this.theme=J,this.props={tabs:[],submit:{active:!1,allAnswered:!1}}}setProps(J){this.props=J}handleInput(J){}invalidate(){}render(J){let $=[" \u2190 "];for(let G of this.props.tabs){let j=` ${G.answered?"\u25A0":"\u25A1"} ${G.label} `,K=G.active?this.theme.bg("selectedBg",this.theme.fg("text",j)):this.theme.fg(G.answered?"success":"muted",j);$.push(K),$.push(" ")}let z=" \u2713 Submit ",Z=this.props.submit.active?this.theme.bg("selectedBg",this.theme.fg("text",z)):this.theme.fg(this.props.submit.allAnswered?"success":"dim",z);return $.push(Z),$.push(" \u2192"),[Qz($.join(""),J,""),""]}}import{DynamicBorder as kz}from"@augmentcode/auggie-v2";import{Container as Bz,Spacer as X$}from"@earendil-works/pi-tui";class OJ{getMax;getCurrent;constructor(J,$){this.getMax=J,this.getCurrent=$}handleInput(J){}invalidate(){}render(J){let $=Math.max(0,this.getMax(J)-this.getCurrent(J));return Array($).fill("")}}import{Container as Uz,Spacer as C,Text as q}from"@earendil-works/pi-tui";var A="(no input)";function y(J,$){switch(J.kind){case"chat":return $==="envelope"?"User wants to chat about this. Continue the conversation to help them decide.":"User wants to chat about this";case"multi":return J.selected&&J.selected.length>0?J.selected.join(", "):"(no input)";case"custom":return J.answer&&J.answer.length>0?J.answer:"(no input)";case"option":return J.answer??"(no input)"}}var Vz="Notes:";class RJ{footerRowCount=4;config;constructor(J){this.config=J}headingRows(J){let $=[],z=this.config.questions[J.currentTab];if(!this.config.isMulti&&z?.header&&z.header.length>0)$.push(new q(this.config.theme.bg("selectedBg",` ${z.header} `),1,0)),$.push(new C(1));if(z)$.push(new q(this.config.theme.bold(z.question),1,0)),$.push(new C(1));return $}bodyComponent(J){let $=this.config.questions[J.currentTab],z=this.config.tabsByIndex[J.currentTab]?.multiSelect;if($?.multiSelect===!0&&z)return z;return this.config.getPreviewPane()}bodyHeight(J,$){return this.config.getCurrentBodyHeight(J)}midRows(J){if(!J.notesVisible)return[];return[new q(this.config.theme.fg("muted",Vz),1,0),this.config.notesInput,new C(1)]}footerRows(J){let $=this.config.questions[J.currentTab];return[new C(1),this.config.chatRow,new C(1),new q(this.config.theme.fg("dim",Fz($,this.config.isMulti,J)),1,0)]}}class AJ{footerRowCount=5;config;constructor(J){this.config=J}headingRows(J){return[new q(this.config.theme.bold(this.config.theme.fg("accent",Z$)),1,0),new C(1)]}bodyComponent(J){let $=new Uz;for(let[z,Z]of this.config.questions.entries()){let Y=J.answers.get(z);if(!Y)continue;let G=Z.header&&Z.header.length>0?Z.header:`Q${z+1}`,X=y(Y,"summary");if($.addChild(new q(this.config.theme.fg("muted",` \u25CF ${G}`),1,0)),$.addChild(new q(` ${this.config.theme.fg("muted","\u2192")} ${this.config.theme.fg("text",X)}`,1,0)),Y.notes&&Y.notes.length>0)$.addChild(new q(this.config.theme.fg("dim",` notes: ${Y.notes}`),1,0))}return $}bodyHeight(J,$){return this.bodyComponent($).render(J).length}midRows(J){return[]}footerRows(J){let $=[];for(let[Y,G]of this.config.questions.entries())if(!J.answers.has(Y))$.push(G.header&&G.header.length>0?G.header:`Q${Y+1}`);let z=$.length===0?this.config.theme.fg("muted",Y$):this.config.theme.fg("warning",`${G$} ${$.join(", ")}`),Z=[new C(1),new q(z,1,0),new C(1)];if(this.config.submitPicker)Z.push(this.config.submitPicker);else Z.push(new C(1)),Z.push(new C(1));return Z}}function Fz(J,$,z){let Z=[i,e];if(J?.multiSelect===!0)Z.push(IJ);if(J&&J.multiSelect!==!0&&z.focusedOptionHasPreview&&!z.notesVisible)Z.push(NJ);if($)Z.push(fJ);return Z.push(t),Z.join(" \xB7 ")}var i="Enter to select",e="\u2191/\u2193 to navigate",IJ="Space to toggle",NJ="n to add notes",fJ="Tab to switch questions",t="Esc to cancel",k8=[i,e,t].join(" \xB7 "),B8=[i,e,fJ,t].join(" \xB7 "),H8=` \xB7 ${IJ}`,C8=` \xB7 ${NJ}`,Z$="Review your answers",Y$="Ready to submit your answers?",G$="\u26A0 Answer remaining questions before submitting:";class gJ{liveProps;config;questionStrategy;submitStrategy;maxFooterRowCount;constructor(J,$){this.config=J,this.liveProps=$,this.questionStrategy=new RJ({theme:J.theme,questions:J.questions,getPreviewPane:()=>this.liveProps.activePreviewPane,tabsByIndex:J.tabsByIndex,notesInput:J.notesInput,chatRow:J.chatRow,isMulti:J.isMulti,getCurrentBodyHeight:J.getCurrentBodyHeight}),this.submitStrategy=J.isMulti?new AJ({theme:J.theme,questions:J.questions,submitPicker:J.submitPicker}):void 0,this.maxFooterRowCount=Math.max(this.questionStrategy.footerRowCount,this.submitStrategy?.footerRowCount??0)}setProps(J){this.liveProps=J}handleInput(J){}invalidate(){}render(J){let z=this.config.isMulti&&this.liveProps.state.currentTab===this.config.questions.length&&this.submitStrategy?this.submitStrategy:this.questionStrategy;return this.buildContainerFromStrategy(z).render(J)}buildContainerFromStrategy(J){let{theme:$,isMulti:z,tabBar:Z}=this.config,Y=this.liveProps.state,G=new Bz,X=()=>new kz((j)=>$.fg("accent",j));if(G.addChild(X()),z&&Z)G.addChild(Z);G.addChild(new X$(1));for(let j of J.headingRows(Y))G.addChild(j);G.addChild(J.bodyComponent(Y)),G.addChild(new X$(1));for(let j of J.midRows(Y))G.addChild(j);G.addChild(X());for(let j of J.footerRows(Y))G.addChild(j);return G.addChild(new OJ((j)=>this.config.getBodyHeight(j)+this.maxFooterRowCount,(j)=>J.bodyHeight(j,Y)+J.footerRowCount)),G}}function JJ(J,$,z){let Z=J[$];if(!Z)return!1;let Y=Z.options[z];return!!Y&&typeof Y.preview==="string"&&Y.preview.length>0}function j$(J){let $=J.filter((z)=>U[z.kind].numbered).length;return{offset:$,total:$+1}}function K$(J,$,z,Z){let Y=J[$];if(!Y||Y.multiSelect===!0)return;let G=z.get($);if(!G||G.kind==="chat")return;if(G.kind==="custom"){let j=Z.findIndex((K)=>K.kind==="other");if(j<0)return;return{index:j,labelOverride:G.answer??""}}if(G.kind!=="option"||typeof G.answer!=="string")return;let X=Z.findIndex((j)=>j.kind==="option"&&j.label===G.answer);if(X<0)return;return{index:X}}function I(J,$){if($<=0)return 0;return Math.min(J,$-1)}function Q$(J,$,z){let Z=I($,z);return J[Z]??[]}function U$(J,$){if(J.notesVisible)return"notes";if(J.currentTab===$)return"submit";if(J.chatFocused)return"chat";return"options"}class _J{tui;questions;itemsByTab;tabsByIndex;inlineInput;globalBindings;perTabBindings;extraInvalidatables;constructor(J){this.tui=J.tui,this.questions=J.questions,this.itemsByTab=J.itemsByTab,this.tabsByIndex=J.tabsByIndex,this.inlineInput=J.inlineInput,this.globalBindings=J.globalBindings,this.perTabBindings=J.perTabBindings,this.extraInvalidatables=J.extraInvalidatables??[]}apply(J){let $=this.questions.length,z=U$(J,$),Z=I(J.currentTab,$),Y=this.tabsByIndex[Z]?.preview??this.tabsByIndex[0]?.preview;if(!Y)throw Error("apply: tabsByIndex is empty \u2014 QuestionnairePropsAdapter requires at least one tab");let G={questions:this.questions,itemsByTab:this.itemsByTab,totalQuestions:$,activeView:z,inputBuffer:this.inlineInput.getValue(),inputCursor:this.inlineInput.getCursor(),activePreviewPane:Y};for(let X of this.globalBindings)X.apply(J,G);for(let[X,j]of this.tabsByIndex.entries()){let K={...G,tab:j,i:X};for(let Q of this.perTabBindings)Q.apply(J,K)}this.tui.requestRender()}invalidate(){for(let J of this.globalBindings)J.invalidate();for(let J of this.tabsByIndex)J.optionList.invalidate(),J.preview.invalidate(),J.multiSelect?.invalidate();for(let J of this.extraInvalidatables)J.invalidate()}}var V$=(J,$)=>{let z=$.questions[$.i];if(!z)return{rows:[],nextActive:!1,nextLabel:U.next.label};let Z=$.activeView==="options",Y=[];for(let K=0;K<z.options.length;K++)Y.push({checked:J.multiSelectChecked.has(K),active:Z&&K===J.optionIndex});let G=Z&&J.optionIndex===z.options.length,j=$.i===$.questions.length-1?sJ:U.next.label;return{rows:Y,nextActive:G,nextLabel:j}},F$=(J,$)=>{let z=$.itemsByTab[$.i]??[],Z=$.activeView==="options",Y=K$($.questions,J.currentTab,J.answers,z);return{selectedIndex:J.optionIndex,focused:Z,inputBuffer:$.inputBuffer,inputCursor:$.inputCursor,...Y?{confirmed:Y}:{}}},k$=(J,$)=>{let z=$.activeView==="submit";return{rows:[{active:z&&J.submitChoiceIndex===0},{active:z&&J.submitChoiceIndex===1}]}},B$=(J,$)=>({notesVisible:J.notesVisible,selectedIndex:J.optionIndex,focused:$.activeView==="options"}),H$=(J,$)=>{return{tabs:$.questions.map((Z,Y)=>({label:Z.header&&Z.header.length>0?Z.header:`Q${Y+1}`,answered:J.answers.has(Y),active:Y===J.currentTab})),submit:{active:J.currentTab===$.questions.length,allAnswered:J.answers.size===$.questions.length&&$.questions.length>0}}},C$=(J,$)=>{let z=Q$($.itemsByTab,J.currentTab,$.totalQuestions);return{focused:$.activeView==="chat",numbering:j$(z)}},M$=(J,$)=>({state:J,activePreviewPane:$.activePreviewPane});function Cz(J){return($)=>({current:J.naturalHeight($),max:J.maxNaturalHeight($)})}function Mz(J){return($)=>{let z=J.naturalHeight($);return{current:z,max:z}}}var q$=(J,$)=>$.i===I(J.currentTab,$.totalQuestions);function D$(J){return new P$(J).build()}class P${tui;theme;questions;itemsByTab;isMulti;initialState;getCurrentTab;selectTheme;markdownTheme=Hz();chatRow;notesInput=new y$;inlineInput=new y$;getTerminalWidth=()=>this.tui.terminal.columns;constructor(J){this.tui=J.tui,this.theme=J.theme,this.questions=J.questions,this.itemsByTab=J.itemsByTab,this.isMulti=J.isMulti,this.initialState=J.initialState,this.getCurrentTab=J.getCurrentTab,this.selectTheme=this.makeSelectTheme(),this.chatRow=new VJ({item:{kind:"chat",label:U.chat.label},theme:this.selectTheme})}build(){let J=this.buildTabComponents();this.injectGlobalLeftWidth(J);let $=this.buildSubmitPicker(),z=this.buildTabBar(),Z=this.buildHeightComputers(J),Y=this.buildDialog(J,$,z,Z),G=this.buildGlobalBindings(Y,$,z),X=this.buildPerTabBindings(),j=this.buildAdapter(J,G,X);return this.handle(j,Y)}makeSelectTheme(){let J=this.theme;return{selectedText:($)=>J.fg("accent",J.bold($)),description:($)=>J.fg("muted",$),scrollInfo:($)=>J.fg("dim",$)}}buildTabComponents(){return this.questions.map((J,$)=>this.buildTabFor(J,$))}buildTabFor(J,$){let z=new HJ({items:this.itemsByTab[$]??[],theme:this.selectTheme}),Z=new n({question:J,theme:this.theme,markdownTheme:this.markdownTheme}),Y=new SJ({question:J,getTerminalWidth:this.getTerminalWidth,optionListView:z,previewBlock:Z}),G=J.multiSelect?new BJ(this.theme,J):void 0,X=this.buildBodyHeights(J,Y,G);return{optionList:z,preview:Y,multiSelect:G,bodyHeights:X}}buildBodyHeights(J,$,z){if(J.multiSelect&&z)return Mz(z);return Cz($)}injectGlobalLeftWidth(J){let $=this.questions,z=this.itemsByTab,Z=$.map((G)=>({multiSelect:G.multiSelect})),Y=(G)=>$$(Z,z,$,G);for(let G of J)G.preview.setGlobalLeftWidth(Y)}buildSubmitPicker(){return this.isMulti?new vJ(this.theme):void 0}buildTabBar(){return this.isMulti?new WJ(this.theme):void 0}buildHeightComputers(J){return{global:(Z)=>{let Y=0;for(let G of J){let X=G.bodyHeights(Z).max;if(X>Y)Y=X}return Math.max(1,Y)},current:(Z)=>{let Y=Math.min(this.getCurrentTab(),J.length-1);return Math.max(0,J[Y]?.bodyHeights(Z).current??0)}}}pickInitialActivePreview(J){let $=I(this.initialState.currentTab,this.questions.length),z=J[$]?.preview??J[0]?.preview;if(!z)throw Error("pickInitialActivePreview: tabs is empty \u2014 buildTabComponents must produce at least one tab");return z}buildDialog(J,$,z,Z){return new gJ({theme:this.theme,questions:this.questions,tabBar:z,notesInput:this.notesInput,chatRow:this.chatRow,isMulti:this.isMulti,tabsByIndex:J,submitPicker:$,getBodyHeight:Z.global,getCurrentBodyHeight:Z.current},{state:this.initialState,activePreviewPane:this.pickInitialActivePreview(J)})}buildGlobalBindings(J,$,z){return[b({component:J,select:M$}),b({component:this.chatRow,select:C$}),...$?[b({component:$,select:k$})]:[],...z?[b({component:z,select:H$})]:[]]}buildPerTabBindings(){return[c({resolve:(J)=>J.optionList,predicate:q$,select:F$}),c({resolve:(J)=>J.preview,predicate:q$,select:B$}),c({resolve:(J)=>J.multiSelect,select:V$})]}buildAdapter(J,$,z){return new _J({tui:this.tui,questions:this.questions,itemsByTab:this.itemsByTab,tabsByIndex:J,inlineInput:this.inlineInput,globalBindings:$,perTabBindings:z,extraInvalidatables:[this.notesInput]})}handle(J,$){return{adapter:J,notesInput:this.notesInput,inlineInput:this.inlineInput,render:(z)=>$.render(z),invalidate:()=>J.invalidate()}}}import{Key as $J,matchesKey as zJ}from"@earendil-works/pi-tui";var ZJ="tui.select.up",m="tui.select.down",N="tui.select.confirm",f="tui.select.cancel",yz="n",qz=" ";function h(J,$){if($<=0)return 0;return(J%$+$)%$}function Dz(J){return J.isMulti?J.questions.length+1:1}function YJ(J,$){if(!$.isMulti)return;if(J.currentTab<$.questions.length-1)return J.currentTab+1;return $.questions.length}function bJ(J,$){let z=$.questions[J.currentTab];if(!z)return null;let Z=$.currentItem;if(Z?.kind==="chat")return{questionIndex:J.currentTab,question:z.question,kind:"chat",answer:Z.label};if(J.inputMode){let Y=$.inputBuffer;return{questionIndex:J.currentTab,question:z.question,kind:"custom",answer:Y.length>0?Y:null}}if(!Z)return null;if(Z.kind==="other")return null;if(Z.kind==="next")return null;return{questionIndex:J.currentTab,question:z.question,kind:"option",answer:Z.label}}function Pz(J,$){let z=$.questions[J.currentTab];if(!z)return[];let Z=[];for(let Y=0;Y<z.options.length;Y++)if(J.multiSelectChecked.has(Y)){let G=z.options[Y]?.label;if(typeof G==="string")Z.push(G)}return Z}function xJ(J,$,z){if(!z.isMulti)return null;let Z=Dz(z);if(zJ(J,$J.tab)||zJ(J,$J.right))return{kind:"tab_switch",nextTab:h($.currentTab+1,Z)};if(zJ(J,$J.shift("tab"))||zJ(J,$J.left))return{kind:"tab_switch",nextTab:h($.currentTab-1,Z)};return null}function L$(J,$){if($.items.length>0&&J.optionIndex===$.items.length-1)return{kind:"focus_chat"};return{kind:"nav",nextIndex:h(J.optionIndex+1,Math.max(1,$.items.length))}}function S$(J,$){if($.items.length>0&&J.optionIndex===0)return{kind:"focus_chat"};return{kind:"nav",nextIndex:h(J.optionIndex-1,Math.max(1,$.items.length))}}function v$(J,$,z){let Z=z.keybindings;if($.notesVisible){if(Z.matches(J,f))return{kind:"notes_exit"};if(Z.matches(J,N))return{kind:"notes_exit"};return{kind:"notes_forward",data:J}}if($.chatFocused){if(Z.matches(J,f))return{kind:"cancel"};if(Z.matches(J,N)){let j=bJ($,z);if(!j)return{kind:"ignore"};return{kind:"confirm",answer:j,autoAdvanceTab:YJ($,z)}}if(Z.matches(J,ZJ))return{kind:"focus_options",optionIndex:Math.max(0,z.items.length-1)};if(Z.matches(J,m))return{kind:"focus_options",optionIndex:0};let X=xJ(J,$,z);if(X)return X;return{kind:"ignore"}}if($.inputMode){if(Z.matches(J,N)){let X=bJ($,z);if(!X)return{kind:"ignore"};return{kind:"confirm",answer:X,autoAdvanceTab:YJ($,z)}}if(Z.matches(J,f))return{kind:"cancel"};if(Z.matches(J,ZJ))return S$($,z);if(Z.matches(J,m))return L$($,z);return{kind:"ignore"}}if(z.isMulti&&$.currentTab===z.questions.length){if(Z.matches(J,f))return{kind:"cancel"};let X=xJ(J,$,z);if(X)return X;if(Z.matches(J,ZJ)||Z.matches(J,m)){let j=Z.matches(J,m)?1:-1;return{kind:"submit_nav",nextIndex:h($.submitChoiceIndex+j,2)===1?1:0}}if(Z.matches(J,N))return $.submitChoiceIndex===1?{kind:"cancel"}:{kind:"submit"};return{kind:"ignore"}}let Y=xJ(J,$,z);if(Y)return Y;let G=z.questions[$.currentTab];if(!G)return{kind:"ignore"};if(J===yz&&!G.multiSelect&&$.focusedOptionHasPreview)return{kind:"notes_enter"};if(Z.matches(J,ZJ))return S$($,z);if(Z.matches(J,m))return L$($,z);if(G.multiSelect){let X=z.currentItem?.kind,j=X?U[X]:void 0;if(J===qz){if(j?.blocksMultiToggle)return{kind:"ignore"};return{kind:"toggle",index:$.optionIndex}}if(Z.matches(J,N)){if(!j?.autoSubmitsInMulti)return{kind:"toggle",index:$.optionIndex};return{kind:"multi_confirm",selected:Pz($,z),autoAdvanceTab:YJ($,z)}}if(Z.matches(J,f))return{kind:"cancel"};return{kind:"ignore"}}if(Z.matches(J,N)){let X=bJ($,z);if(!X)return{kind:"ignore"};return{kind:"confirm",answer:X,autoAdvanceTab:YJ($,z)}}if(Z.matches(J,f))return{kind:"cancel"};return{kind:"ignore"}}function Lz(J,$){let z=[];for(let Z=0;Z<$.length;Z++){let Y=J.answers.get(Z);if(Y)z.push(Y)}return z}function TJ(J,$){let z=JJ($,J.currentTab,J.optionIndex);if(J.focusedOptionHasPreview===z)return J;return{...J,focusedOptionHasPreview:z}}function W$(J,$,z){let Z=$[z];if(!Z?.multiSelect)return new Set;let G=J.get(z)?.selected??[],X=new Set;for(let[j,K]of Z.options.entries())if(G.includes(K.label))X.add(j);return X}function Sz(J,$){let z=$.questions[J.currentTab];if(!z?.multiSelect)return J.answers;let Z=[];for(let[X,j]of z.options.entries())if(J.multiSelectChecked.has(X))Z.push(j.label);let Y=new Map(J.answers);if(Z.length===0)return Y.delete(J.currentTab),Y;let G=J.notesByTab.get(J.currentTab);return Y.set(J.currentTab,{questionIndex:J.currentTab,question:z.question,kind:"multi",answer:null,selected:Z,...G&&G.length>0?{notes:G}:{}}),Y}function EJ(J,$,z){let Z=J.notesByTab.get($)??J.answers.get($)?.notes??"",Y={...J,currentTab:$,optionIndex:0,inputMode:!1,notesVisible:!1,chatFocused:!1,submitChoiceIndex:0,multiSelectChecked:W$(J.answers,z.questions,$),notesDraft:Z};return{state:TJ(Y,z.questions),effects:[{kind:"set_notes_focused",focused:!1},{kind:"set_notes_value",value:Z}]}}function p(J,$,z){let Z={answers:Lz(J,$.questions),cancelled:z};return{state:J,effects:[{kind:"done",result:Z}]}}var vz=(J,$,z)=>{let Y=(z.itemsByTab[J.currentTab]??[])[$.nextIndex],G=Y?U[Y.kind].activatesInputMode:!1,X=TJ({...J,optionIndex:$.nextIndex,inputMode:G},z.questions);if(!G)return{state:X,effects:[{kind:"clear_input_buffer"}]};let j=J.answers.get(J.currentTab);if(j?.kind==="custom"&&typeof j.answer==="string")return{state:X,effects:[{kind:"set_input_buffer",value:j.answer}]};return{state:X,effects:[]}},Wz=(J,$,z)=>EJ(J,$.nextTab,z),Oz=(J,$,z)=>{let Z=$.answer;if(Z.kind==="option"&&Z.answer){let K=z.questions[Z.questionIndex]?.options.find((Q)=>Q.label===Z.answer);if(K?.preview&&K.preview.length>0)Z={...Z,preview:K.preview}}let Y=J.notesByTab.get(Z.questionIndex);if(Y&&Y.length>0)Z={...Z,notes:Y};let G=new Map(J.answers);G.set(Z.questionIndex,Z);let X={...J,answers:G};if(Z.kind==="chat")return p(X,z,!1);if($.autoAdvanceTab!==void 0)return EJ(X,$.autoAdvanceTab,z);return p(X,z,!1)},Rz=(J,$,z)=>{let Z=new Set(J.multiSelectChecked);if(Z.has($.index))Z.delete($.index);else Z.add($.index);let Y={...J,multiSelectChecked:Z},G=Sz(Y,z);return{state:{...Y,answers:G},effects:[]}},Az=(J,$,z)=>{let Z=z.questions[J.currentTab];if(!Z)return{state:J,effects:[]};let Y=J.notesByTab.get(J.currentTab),G=new Map(J.answers);G.set(J.currentTab,{questionIndex:J.currentTab,question:Z.question,kind:"multi",answer:null,selected:$.selected,...Y&&Y.length>0?{notes:Y}:{}});let X={...J,answers:G,multiSelectChecked:W$(G,z.questions,J.currentTab)};if($.autoAdvanceTab!==void 0)return EJ(X,$.autoAdvanceTab,z);return p(X,z,!1)},Iz=(J,$,z)=>{let Z=J.notesByTab.get(J.currentTab)??J.answers.get(J.currentTab)?.notes??"";return{state:{...J,notesVisible:!0,notesDraft:Z},effects:[{kind:"set_notes_value",value:Z},{kind:"set_notes_focused",focused:!0}]}},Nz=(J,$,z)=>{let Z=J.notesDraft.trim(),Y=new Map(J.notesByTab),G=new Map(J.answers);if(Z.length===0){Y.delete(J.currentTab);let X=G.get(J.currentTab);if(X?.notes){let j={...X};j.notes=void 0,G.set(J.currentTab,j)}}else{Y.set(J.currentTab,Z);let X=G.get(J.currentTab);if(X)G.set(J.currentTab,{...X,notes:Z})}return{state:{...J,notesByTab:Y,answers:G,notesVisible:!1},effects:[{kind:"set_notes_focused",focused:!1}]}},fz=(J,$,z)=>{let Y=(z.itemsByTab[J.currentTab]??[])[$.optionIndex],G=Y?U[Y.kind].activatesInputMode:!1;return{state:TJ({...J,chatFocused:!1,optionIndex:$.optionIndex,inputMode:G},z.questions),effects:G?[]:[{kind:"clear_input_buffer"}]}},gz=(J,$,z)=>p(J,z,!0),_z=(J,$,z)=>p(J,z,!1),bz=(J,$,z)=>({state:{...J,submitChoiceIndex:$.nextIndex},effects:[]}),xz=(J,$,z)=>({state:{...J,chatFocused:!0},effects:[]}),Tz=(J,$,z)=>({state:J,effects:[{kind:"forward_notes_keystroke",data:$.data}]}),Ez=(J,$,z)=>({state:J,effects:[]}),wz={nav:vz,tab_switch:Wz,confirm:Oz,toggle:Rz,multi_confirm:Az,cancel:gz,notes_enter:Iz,notes_exit:Nz,notes_forward:Tz,submit:_z,submit_nav:bz,focus_chat:xz,focus_options:fz,ignore:Ez};function O$(J,$,z){let Z=wz[$.kind];return Z(J,$,z)}var hz="\x05";function pz(){return{currentTab:0,optionIndex:0,inputMode:!1,notesVisible:!1,chatFocused:!1,answers:new Map,multiSelectChecked:new Set,notesByTab:new Map,focusedOptionHasPreview:!1,submitChoiceIndex:0,notesDraft:""}}class wJ{state=pz();questions;isMulti;itemsByTab;notesInput;inlineInput;viewAdapter;tui;done;component;constructor(J){this.tui=J.tui,this.done=J.done,this.questions=J.params.questions,this.isMulti=this.questions.length>1,this.itemsByTab=J.itemsByTab,this.state={...this.state,focusedOptionHasPreview:JJ(this.questions,0,0)};let $=D$({tui:this.tui,theme:J.theme,questions:this.questions,itemsByTab:this.itemsByTab,isMulti:this.isMulti,initialState:this.state,getCurrentTab:()=>this.state.currentTab});this.notesInput=$.notesInput,this.inlineInput=$.inlineInput,this.viewAdapter=$.adapter,this.component={render:$.render,invalidate:$.invalidate,handleInput:(z)=>this.dispatch(z)},this.viewAdapter.apply(this.state)}dispatch(J){let $=v$(J,this.state,this.runtime());if($.kind==="ignore"){this.handleIgnoreInline(J);return}this.commit($)}commit(J){let $=O$(this.state,J,this.applyContext());this.state=$.state;for(let z of $.effects)this.runEffect(z);this.state=this.mirrorNotesDraft(this.state),this.viewAdapter.apply(this.state)}mirrorNotesDraft(J){let $=this.notesInput.getValue();return J.notesDraft===$?J:{...J,notesDraft:$}}runEffect(J){switch(J.kind){case"set_input_buffer":this.inlineInput.setValue(J.value),this.inlineInput.handleInput(hz);return;case"clear_input_buffer":this.inlineInput.setValue("");return;case"set_notes_value":this.notesInput.setValue(J.value);return;case"set_notes_focused":this.notesInput.focused=J.focused;return;case"forward_notes_keystroke":this.notesInput.handleInput(J.data);return;case"done":this.done(J.result);return}}handleIgnoreInline(J){if(!this.state.inputMode)return;this.inlineInput.handleInput(J),this.viewAdapter.apply(this.state)}runtime(){return{keybindings:mz(),inputBuffer:this.inlineInput.getValue(),questions:this.questions,isMulti:this.isMulti,currentItem:this.currentItem(),items:this.itemsByTab[this.state.currentTab]??[]}}applyContext(){return{questions:this.questions,itemsByTab:this.itemsByTab}}currentItem(){if(this.state.chatFocused)return{kind:"chat",label:U.chat.label};let J=this.itemsByTab[this.state.currentTab]??[];if(this.state.optionIndex<J.length)return J[this.state.optionIndex];return{kind:"chat",label:U.chat.label}}}var lz="ask-user",GJ=" - ";function mJ(J,$){let z=$.fg("toolTitle",$.bold(lz));switch(J.kind){case"preparing":return`${z}${GJ}${$.fg("dim","preparing...")}`;case"waiting":case"answered":{let Z=$.fg("accent",uz(J.questionCount));return`${z}${GJ}${Z}`}case"declined":return`${z}${GJ}${$.fg("warning","declined")}`;case"error":{let Z=J.code!==void 0&&J.code.length>0?`error: ${J.code}`:"error";return`${z}${GJ}${$.fg("error",Z)}`}default:return I$(J)}}function uz(J){return J===1?"1 question":`${J} questions`}var R$=60,cz="*",dz="->",oz="chat about this";function A$(J,$,z){if(J.length===0)return[];let Z=rz(J),Y=[];for(let G=0;G<J.length;G++){let X=J[G],j=$.find((K)=>K.questionIndex===G);Y.push(az(X,j,Z,z))}return Y}function rz(J){let $=0;for(let z of J)if(z.header.length>$)$=z.header.length;return $}function nz(J,$){if(J.length>=$)return J;return J+" ".repeat($-J.length)}function sz(J){let $=J.length;if($<=R$)return{display:J,truncated:!1,length:$};return{display:`${J.slice(0,R$-3)}...`,truncated:!0,length:$}}function az(J,$,z,Z){let Y=Z.fg("muted",cz),G=Z.fg("dim",nz(J.header,z)),X=Z.fg("muted",dz),j=iz($,Z),K=ez($,Z);return` ${Y} ${G} ${X} ${j}${K}`}function iz(J,$){if(!J)return $.fg("dim",A);switch(J.kind){case"chat":return $.fg("dim",`(${oz})`);case"custom":{let z=y(J,"summary");if(z===A)return $.fg("dim",z);let{display:Z,truncated:Y,length:G}=sz(z),X=$.fg("accent",`"${Z}"`);if(!Y)return X;return X+$.fg("muted",` - ${G} chars`)}case"option":case"multi":{let z=y(J,"summary");if(z===A)return $.fg("dim",z);return $.fg("accent",z)}default:return I$(J.kind)}}function ez(J,$){if(!J)return"";let z="";if(J.notes&&J.notes.length>0)z+=$.fg("muted"," - notes");if(J.preview&&J.preview.length>0)z+=$.fg("muted"," - preview");return z}function I$(J){throw Error(`Unhandled discriminant: ${JSON.stringify(J)}`)}var N$="User declined to answer questions",tz="User has answered your questions:",J7="You can now continue with the user's answers in mind.";function f$(J,$){if(!J||J.cancelled)return g(N$,{answers:J?.answers??[],cancelled:!0});let z=[];for(let Z=0;Z<$.questions.length;Z++){let Y=J.answers.find((G)=>G.questionIndex===Z);if(Y)z.push($7(Y))}if(z.length===0)return g(N$,{answers:J.answers,cancelled:!0});return g(`${tz} ${z.join(" ")} ${J7}`,J)}function $7(J){let $=[`"${J.question}"="${y(J,"envelope")}"`];if(J.preview&&J.preview.length>0)$.push(`selected preview: ${J.preview}`);if(J.notes&&J.notes.length>0)$.push(`user notes: ${J.notes}`);return`${$.join(". ")}.`}function g(J,$){return{content:[{type:"text",text:J}],details:$}}import{Type as k}from"@sinclair/typebox";var v=4,W=2,XJ=4,l=16,S=60;var hJ=["Other",U.other.label,U.chat.label,U.next.label],z7=k.Object({label:k.String({maxLength:S,description:`MAX ${S} CHARACTERS \u2014 hard limit, requests over the limit are rejected. The display text for this option that the user will see and select. Should be concise (1-5 words) and clearly describe the choice. Do NOT append "(Recommended)" to the label text \u2014 set the "recommended" flag on the option instead; the renderer adds the marker automatically.`}),description:k.String({description:"Explanation of what this option means or what will happen if chosen. Useful for providing context about trade-offs or implications."}),preview:k.Optional(k.String({description:"Optional preview content rendered when this option is focused. Use for mockups, code snippets, or visual comparisons that help users compare options. See the tool description for the expected content format."})),recommended:k.Optional(k.Boolean({description:`If true, the renderer marks this option as the recommended choice by appending "(Recommended)" after the label at display time. Use this instead of typing "(Recommended)" into the label yourself \u2014 that text counts against the ${S}-character label cap and the schema will reject it.`}))}),Z7=k.Object({question:k.String({description:'The complete question to ask the user. Should be clear, specific, and end with a question mark. Example: "Which library should we use for date formatting?" If multiSelect is true, phrase it accordingly, e.g. "Which features do you want to enable?"'}),header:k.String({maxLength:l,description:`MAX ${l} CHARACTERS \u2014 hard limit, requests over the limit are rejected. Very short chip/tag shown next to the question. Examples: "Auth method", "Library", "Approach".`}),options:k.Array(z7,{minItems:W,maxItems:XJ,description:"The available choices for this question. Must have 2-4 options. Each option should be a distinct, mutually exclusive choice (unless multiSelect is enabled). The 'Type something.' row is appended automatically \u2014 do NOT author it."}),multiSelect:k.Optional(k.Boolean({default:!1,description:"Set to true to allow the user to select multiple options instead of just one. Use when choices are not mutually exclusive."}))}),Y7=k.Array(Z7,{minItems:1,maxItems:v,description:"Questions to ask the user (1-4 questions)"}),g$=k.Object({questions:Y7});var G7="Error: At least one question is required",X7=`Error: At most ${v} questions are allowed per invocation`,j7="Error: Question text must be unique within an invocation",K7=`Error: Each question requires at least ${W} options`,Q7=`Error: Option label is reserved (${hJ.join(", ")})`,U7="Error: Option labels must be unique within a question",V7=new Set(hJ);function _$(J){if(J.questions.length===0)return{ok:!1,error:"no_questions",message:G7};if(J.questions.length>v)return{ok:!1,error:"too_many_questions",message:X7};let $=new Set;for(let z of J.questions){if($.has(z.question))return{ok:!1,error:"duplicate_question",message:j7};$.add(z.question)}for(let z of J.questions){if(z.options.length<W)return{ok:!1,error:"empty_options",message:K7};let Z=new Set;for(let Y of z.options){if(V7.has(Y.label))return{ok:!1,error:"reserved_label",message:Q7};if(Z.has(Y.label))return{ok:!1,error:"duplicate_option_label",message:U7};Z.add(Y.label)}}return{ok:!0}}var k7="Error: UI not available (running in non-interactive mode)",b$=" (Recommended)",B7="\u2026";function T$(J,$){let z=Array.from(J);if(z.length<=$)return J;return`${z.slice(0,$-1).join("")}${B7}`}function H7(J){if(!J||typeof J!=="object")return J;let $=J;if(typeof $.label!=="string")return J;let z=$.label,Z=!1,Y=!1;if(z.endsWith(b$)){if(z=z.slice(0,z.length-b$.length),$.recommended==null)Z=!0;Y=!0}if(z.length>S)z=T$(z,S),Y=!0;if(!Y)return J;if(Z)return{...J,label:z,recommended:!0};return{...J,label:z}}function C7(J){if(!J||typeof J!=="object")return J;let $=J,z=$.header,Z=!1;if(typeof $.header==="string"&&$.header.length>l)z=T$($.header,l),Z=!0;let Y=$.options,G=!1;if(Array.isArray($.options)){let X=$.options,j=X.map(H7);if(G=j.some((K,Q)=>K!==X[Q]),G)Y=j}if(!(Z||G))return J;return{...J,header:z,options:Y}}function M7(J){if(!J||typeof J!=="object")return J;let $=J;if(!Array.isArray($.questions))return J;let z=$.questions,Z=z.map(C7);if(!Z.some((G,X)=>G!==z[X]))return J;return{...$,questions:Z}}function y7(J){let $=J.options.map((Z)=>({kind:"option",label:Z.label,description:Z.description,...Z.recommended===!0?{recommended:!0}:{}})),z=J.options.some((Z)=>typeof Z.preview==="string"&&Z.preview.length>0);for(let Z of uJ(J,z))$.push({kind:Z,label:U[Z].label});return $}function x$(J){let{args:$,executionStarted:z,argsComplete:Z,result:Y}=J;if(Y){if(Y.isError)return{kind:"error",code:Y.details?.error};if(Y.details?.cancelled)return{kind:"declined"};let G=$?.questions??[],X=Y.details?.answers??[];return{kind:"answered",questionCount:G.length,unanswered:q7(G,X)}}if(Z&&z)return{kind:"waiting",questionCount:$?.questions?.length??0};return{kind:"preparing"}}function q7(J,$){let z=0;for(let Z=0;Z<J.length;Z++){let Y=$.find((G)=>G.questionIndex===Z);if(!Y){z++;continue}if(Y.kind==="chat"){z++;continue}if(y(Y,"summary")===A)z++}return z}function E$(J){J.registerTool({name:"ask-user",label:"Ask User Question",description:`Ask the user one or more structured questions during execution. Use when you need to:
4
+ 1. Gather user preferences or requirements
5
+ 2. Clarify ambiguous instructions
6
+ 3. Get decisions on implementation choices as you work
7
+ 4. Offer choices to the user about what direction to take
8
+
9
+ Usage notes:
10
+ - Users will always be able to type a custom answer ("Type something." row is appended automatically to every single-select question) or pick "Chat about this" to abandon the questionnaire and continue in free-form conversation. Do NOT author "Other" / "Type something." / "Chat about this" labels yourself \u2014 duplicates are rejected at runtime.
11
+ - Use multiSelect: true to allow multiple answers to be selected for a question. The "Type something." row is suppressed on multi-select questions, and is ALSO suppressed on single-select questions where any option carries a \`preview\` (the side-by-side layout has no room for inline custom text \u2014 "Chat about this" remains as the free-form escape hatch).
12
+ - Every option's \`label\` is capped at 60 characters and every question's \`header\` at 16 characters \u2014 over-limit values are rejected by the tool schema.
13
+ - If one option is your recommendation, make it the first option in the list AND set \`recommended: true\` on it. Do NOT append "(Recommended)" to the label text \u2014 that suffix counts against the 60-character label budget; the renderer adds the marker automatically when \`recommended\` is set.
14
+
15
+ Preview feature:
16
+ Use the optional \`preview\` field on options when presenting concrete artifacts that users need to visually compare:
17
+ - ASCII mockups of UI layouts or components
18
+ - Code snippets showing different implementations
19
+ - Diagram variations
20
+ - Configuration examples
21
+
22
+ Preview content is rendered as markdown in a monospace box. Multi-line text with newlines is supported. When any option has a preview, the UI switches to a side-by-side layout with a vertical option list on the left and preview on the right. Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).`,promptSnippet:`Ask the user up to ${v} structured questions (${W}-${XJ} options each) when requirements are ambiguous`,promptGuidelines:[`Use ask-user whenever the user's request is underspecified and you cannot proceed without concrete decisions \u2014 you can ask up to ${v} questions per invocation.`,`Each question MUST have ${W}-${XJ} options. Every option requires a concise label (1-5 words) and a description explaining what the choice means or its trade-offs. The user can additionally type a custom answer ("Type something." row is appended automatically to single-select questions) or pick "Chat about this" to abandon the questionnaire.`,`Set multiSelect: true when multiple answers are valid; this suppresses the "Type something." row. Provide an options[].preview markdown string when an option benefits from richer side-by-side context (mockups, code snippets, diagrams, configs) \u2014 single-select only. NOTE: any non-empty preview on a single-select question ALSO suppresses the "Type something." row (no room in the side-by-side layout); "Chat about this" remains the escape hatch. If you recommend a specific option, make it the first option and set recommended: true on it (do NOT type "(Recommended)" into the label \u2014 the renderer adds the marker, and the suffix would count against the ${S}-character label cap). The recommended flag is only meaningful on single-select questions \u2014 do not set it on multi-select options, where "choose any that apply" makes a single-row recommendation semantically odd.`,"Do not stack multiple ask-user calls back-to-back \u2014 group all clarifying questions into one invocation."],parameters:g$,prepareArguments:M7,defaultExpanded:!0,renderCall($,z,Z){let Y=Z.lastComponent??new jJ("",0,0);if(Z.argsComplete&&Z.executionStarted&&!Z.isPartial)return Y.setText(""),Y;let G=x$({args:$,executionStarted:Z.executionStarted,argsComplete:Z.argsComplete,isPartial:Z.isPartial,result:void 0});return Y.setText(mJ(G,z)),Y},renderResult($,z,Z,Y){let G=Y.lastComponent??new F7;G.clear();let X=x$({args:Y.args,executionStarted:Y.executionStarted,argsComplete:Y.argsComplete,isPartial:Y.isPartial,result:{isError:Y.isError,details:$.details}});if(G.addChild(new jJ(mJ(X,Z),0,0)),X.kind==="error"){let j=$.content[0];if(j?.type==="text"&&j.text.length>0)G.addChild(new jJ(` ${Z.fg("toolOutput",j.text)}`,0,0));return G}if(X.kind==="answered"||X.kind==="declined"){let K=Y.args?.questions??[],Q=$.details?.answers??[];if(X.kind==="declined"&&Q.length===0)return G;for(let V of A$(K,Q,Z))G.addChild(new jJ(V,0,0))}return G},async execute($,z,Z,Y,G){let X=z;if(!G.hasUI)return g(k7,{answers:[],cancelled:!0,error:"no_ui"});let j=_$(X);if(!j.ok)return g(j.message,{answers:[],cancelled:!0,error:j.error});let K=X.questions.map((V)=>y7(V)),Q=await G.ui.custom((V,F,B,D)=>{return new wJ({tui:V,theme:F,params:X,itemsByTab:K,done:D}).component});return f$(Q,X)}})}var w$="ask-user";function D7(J){E$(J),J.on("session_start",($,z)=>{if(z.mode==="interactive")return;let Z=J.getActiveTools();if(!Z.includes(w$))return;J.setActiveTools(Z.filter((Y)=>Y!==w$))})}export{D7 as default};
23
+
24
+ //# debugId=0DF9938503E3B49E64756E2164756E21
@@ -0,0 +1,12 @@
1
+ {
2
+ "extensions": [
3
+ {
4
+ "name": "ask-user",
5
+ "entry": "ask-user/index.js"
6
+ },
7
+ {
8
+ "name": "mcp",
9
+ "entry": "mcp/index.js"
10
+ }
11
+ ]
12
+ }