opencode-webui 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{index-D2GMPF3o.js → index-Ca0YxAh-.js} +1 -1
- package/dist/assets/{report-bjdxXk2S.js → report-BVQPFnRg.js} +1 -1
- package/dist/assets/{runtime-status-DGOzOYuv.js → runtime-status-CHh7J96X.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/skills/webui/SKILL.md +36 -3
|
@@ -119,4 +119,4 @@ WARNING: This link could potentially be dangerous`)){let e=window.open();if(e){t
|
|
|
119
119
|
`&&(this._liveRegionLineCount++,this._liveRegionLineCount===zW+1&&(this._liveRegion.textContent+=lL.get())))}_clearLiveRegion(){this._liveRegion.textContent=``,this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){let n=this._terminal.buffer,r=n.lines.length.toString();for(let i=e;i<=t;i++){let e=n.lines.get(n.ydisp+i),t=[],a=e?.translateToString(!0,void 0,void 0,t)||``,o=(n.ydisp+i+1).toString(),s=this._rowElements[i];s&&(a.length===0?(s.textContent=`\xA0`,this._rowColumns.set(s,[0,1])):(s.textContent=a,this._rowColumns.set(s,t)),s.setAttribute(`aria-posinset`,o),s.setAttribute(`aria-setsize`,r),this._alignRowWidth(s))}this._announceCharacters()}_announceCharacters(){this._charsToAnnounce.length!==0&&(this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce=``)}_handleBoundaryFocus(e,t){let n=e.target,r=this._rowElements[t===0?1:this._rowElements.length-2];if(n.getAttribute(`aria-posinset`)===(t===0?`1`:`${this._terminal.buffer.lines.length}`)||e.relatedTarget!==r)return;let i,a;if(t===0?(i=n,a=this._rowElements.pop(),this._rowContainer.removeChild(a)):(i=this._rowElements.shift(),a=n,this._rowContainer.removeChild(i)),i.removeEventListener(`focus`,this._topBoundaryFocusListener),a.removeEventListener(`focus`,this._bottomBoundaryFocusListener),t===0){let e=this._createAccessibilityTreeNode();this._rowElements.unshift(e),this._rowContainer.insertAdjacentElement(`afterbegin`,e)}else{let e=this._createAccessibilityTreeNode();this._rowElements.push(e),this._rowContainer.appendChild(e)}this._rowElements[0].addEventListener(`focus`,this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener(`focus`,this._bottomBoundaryFocusListener),this._terminal.scrollLines(t===0?-1:1),this._rowElements[t===0?1:this._rowElements.length-2].focus(),e.preventDefault(),e.stopImmediatePropagation()}_handleSelectionChange(){if(this._rowElements.length===0)return;let e=this._coreBrowserService.mainDocument.getSelection();if(!e)return;if(e.isCollapsed){this._rowContainer.contains(e.anchorNode)&&this._terminal.clearSelection();return}if(!e.anchorNode||!e.focusNode){console.error(`anchorNode and/or focusNode are null`);return}let t={node:e.anchorNode,offset:e.anchorOffset},n={node:e.focusNode,offset:e.focusOffset};if((t.node.compareDocumentPosition(n.node)&Node.DOCUMENT_POSITION_PRECEDING||t.node===n.node&&t.offset>n.offset)&&([t,n]=[n,t]),t.node.compareDocumentPosition(this._rowElements[0])&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_FOLLOWING)&&(t={node:this._rowElements[0].childNodes[0],offset:0}),!this._rowContainer.contains(t.node))return;let r=this._rowElements.slice(-1)[0];if(n.node.compareDocumentPosition(r)&(Node.DOCUMENT_POSITION_CONTAINED_BY|Node.DOCUMENT_POSITION_PRECEDING)&&(n={node:r,offset:r.textContent?.length??0}),!this._rowContainer.contains(n.node))return;let i=({node:e,offset:t})=>{let n=e instanceof Text?e.parentNode:e,r=parseInt(n?.getAttribute(`aria-posinset`),10)-1;if(isNaN(r))return console.warn(`row is invalid. Race condition?`),null;let i=this._rowColumns.get(n);if(!i)return console.warn(`columns is null. Race condition?`),null;let a=t<i.length?i[t]:i.slice(-1)[0]+1;return a>=this._terminal.cols&&(++r,a=0),{row:r,column:a}},a=i(t),o=i(n);if(!(!a||!o)){if(a.row>o.row||a.row===o.row&&a.column>=o.column)throw Error(`invalid range`);this._terminal.select(a.column,a.row,(o.row-a.row)*this._terminal.cols-a.column+o.column)}}_handleResize(e){this._rowElements[this._rowElements.length-1].removeEventListener(`focus`,this._bottomBoundaryFocusListener);for(let e=this._rowContainer.children.length;e<this._terminal.rows;e++)this._rowElements[e]=this._createAccessibilityTreeNode(),this._rowContainer.appendChild(this._rowElements[e]);for(;this._rowElements.length>e;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener(`focus`,this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){let e=this._coreBrowserService.mainDocument.createElement(`div`);return e.setAttribute(`role`,`listitem`),e.tabIndex=-1,this._refreshRowDimensions(e),e}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){Object.assign(this._accessibilityContainer.style,{width:`${this._renderService.dimensions.css.canvas.width}px`,fontSize:`${this._terminal.options.fontSize}px`}),this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let e=0;e<this._terminal.rows;e++)this._refreshRowDimensions(this._rowElements[e]),this._alignRowWidth(this._rowElements[e])}}_refreshRowDimensions(e){e.style.height=`${this._renderService.dimensions.css.cell.height}px`}_alignRowWidth(e){e.style.transform=``;let t=e.getBoundingClientRect().width,n=this._rowColumns.get(e)?.slice(-1)?.[0];if(!n)return;let r=n*this._renderService.dimensions.css.cell.width;e.style.transform=`scaleX(${r/t})`}};BW=aL([Z(1,IL),Z(2,GL),Z(3,qL)],BW);var VW=class extends xR{constructor(e,t,n,r,i){super(),this._element=e,this._mouseService=t,this._renderService=n,this._bufferService=r,this._linkProviderService=i,this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this._register(new Q),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this._register(new Q),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this._register(vR(()=>{gR(this._linkCacheDisposables),this._linkCacheDisposables.length=0,this._lastMouseEvent=void 0,this._activeProviderReplies?.clear()})),this._register(this._bufferService.onResize(()=>{this._clearCurrentLink(),this._wasResized=!0})),this._register(fB(this._element,`mouseleave`,()=>{this._isMouseOut=!0,this._clearCurrentLink()})),this._register(fB(this._element,`mousemove`,this._handleMouseMove.bind(this))),this._register(fB(this._element,`mousedown`,this._handleMouseDown.bind(this))),this._register(fB(this._element,`mouseup`,this._handleMouseUp.bind(this)))}get currentLink(){return this._currentLink}_handleMouseMove(e){this._lastMouseEvent=e;let t=this._positionFromMouseEvent(e,this._element,this._mouseService);if(!t)return;this._isMouseOut=!1;let n=e.composedPath();for(let e=0;e<n.length;e++){let t=n[e];if(t.classList.contains(`xterm`))break;if(t.classList.contains(`xterm-hover`))return}(!this._lastBufferCell||t.x!==this._lastBufferCell.x||t.y!==this._lastBufferCell.y)&&(this._handleHover(t),this._lastBufferCell=t)}_handleHover(e){if(this._activeLine!==e.y||this._wasResized){this._clearCurrentLink(),this._askForLink(e,!1),this._wasResized=!1;return}this._currentLink&&this._linkAtPosition(this._currentLink.link,e)||(this._clearCurrentLink(),this._askForLink(e,!0))}_askForLink(e,t){(!this._activeProviderReplies||!t)&&(this._activeProviderReplies?.forEach(e=>{e?.forEach(e=>{e.link.dispose&&e.link.dispose()})}),this._activeProviderReplies=new Map,this._activeLine=e.y);let n=!1;for(let[r,i]of this._linkProviderService.linkProviders.entries())t?this._activeProviderReplies?.get(r)&&(n=this._checkLinkProviderResult(r,e,n)):i.provideLinks(e.y,t=>{if(this._isMouseOut)return;let i=t?.map(e=>({link:e}));this._activeProviderReplies?.set(r,i),n=this._checkLinkProviderResult(r,e,n),this._activeProviderReplies?.size===this._linkProviderService.linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)})}_removeIntersectingLinks(e,t){let n=new Set;for(let r=0;r<t.size;r++){let i=t.get(r);if(i)for(let t=0;t<i.length;t++){let r=i[t],a=r.link.range.start.y<e?0:r.link.range.start.x,o=r.link.range.end.y>e?this._bufferService.cols:r.link.range.end.x;for(let e=a;e<=o;e++){if(n.has(e)){i.splice(t--,1);break}n.add(e)}}}}_checkLinkProviderResult(e,t,n){if(!this._activeProviderReplies)return n;let r=this._activeProviderReplies.get(e),i=!1;for(let t=0;t<e;t++)(!this._activeProviderReplies.has(t)||this._activeProviderReplies.get(t))&&(i=!0);if(!i&&r){let e=r.find(e=>this._linkAtPosition(e.link,t));e&&(n=!0,this._handleNewLink(e))}if(this._activeProviderReplies.size===this._linkProviderService.linkProviders.length&&!n)for(let e=0;e<this._activeProviderReplies.size;e++){let r=this._activeProviderReplies.get(e)?.find(e=>this._linkAtPosition(e.link,t));if(r){n=!0,this._handleNewLink(r);break}}return n}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._currentLink)return;let t=this._positionFromMouseEvent(e,this._element,this._mouseService);t&&this._mouseDownLink&&HW(this._mouseDownLink.link,this._currentLink.link)&&this._linkAtPosition(this._currentLink.link,t)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,t){!this._currentLink||!this._lastMouseEvent||(!e||!t||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=t)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,gR(this._linkCacheDisposables),this._linkCacheDisposables.length=0)}_handleNewLink(e){if(!this._lastMouseEvent)return;let t=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);t&&this._linkAtPosition(e.link,t)&&(this._currentLink=e,this._currentLink.state={decorations:{underline:e.link.decorations===void 0||e.link.decorations.underline,pointerCursor:e.link.decorations===void 0||e.link.decorations.pointerCursor},isHovered:!0},this._linkHover(this._element,e.link,this._lastMouseEvent),e.link.decorations={},Object.defineProperties(e.link.decorations,{pointerCursor:{get:()=>this._currentLink?.state?.decorations.pointerCursor,set:e=>{this._currentLink?.state&&this._currentLink.state.decorations.pointerCursor!==e&&(this._currentLink.state.decorations.pointerCursor=e,this._currentLink.state.isHovered&&this._element.classList.toggle(`xterm-cursor-pointer`,e))}},underline:{get:()=>this._currentLink?.state?.decorations.underline,set:t=>{this._currentLink?.state&&this._currentLink?.state?.decorations.underline!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e=>{if(!this._currentLink)return;let t=e.start===0?0:e.start+1+this._bufferService.buffer.ydisp,n=this._bufferService.buffer.ydisp+1+e.end;if(this._currentLink.link.range.start.y>=t&&this._currentLink.link.range.end.y<=n&&(this._clearCurrentLink(t,n),this._lastMouseEvent)){let e=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);e&&this._askForLink(e,!1)}})))}_linkHover(e,t,n){this._currentLink?.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add(`xterm-cursor-pointer`)),t.hover&&t.hover(n,t.text)}_fireUnderlineEvent(e,t){let n=e.range,r=this._bufferService.buffer.ydisp,i=this._createLinkUnderlineEvent(n.start.x-1,n.start.y-r-1,n.end.x,n.end.y-r-1,void 0);(t?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(i)}_linkLeave(e,t,n){this._currentLink?.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(t,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove(`xterm-cursor-pointer`)),t.leave&&t.leave(n,t.text)}_linkAtPosition(e,t){let n=e.range.start.y*this._bufferService.cols+e.range.start.x,r=e.range.end.y*this._bufferService.cols+e.range.end.x,i=t.y*this._bufferService.cols+t.x;return n<=i&&i<=r}_positionFromMouseEvent(e,t,n){let r=n.getCoords(e,t,this._bufferService.cols,this._bufferService.rows);if(r)return{x:r[0],y:r[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,t,n,r,i){return{x1:e,y1:t,x2:n,y2:r,cols:this._bufferService.cols,fg:i}}};VW=aL([Z(1,KL),Z(2,qL),Z(3,ML),Z(4,ZL)],VW);function HW(e,t){return e.text===t.text&&e.range.start.x===t.range.start.x&&e.range.start.y===t.range.start.y&&e.range.end.x===t.range.end.x&&e.range.end.y===t.range.end.y}var UW=class extends OW{constructor(e={}){super(e),this._linkifier=this._register(new SR),this.browser=tH,this._keyDownHandled=!1,this._keyDownSeen=!1,this._keyPressHandled=!1,this._unprocessedDeadKey=!1,this._accessibilityManager=this._register(new SR),this._onCursorMove=this._register(new Q),this.onCursorMove=this._onCursorMove.event,this._onKey=this._register(new Q),this.onKey=this._onKey.event,this._onRender=this._register(new Q),this.onRender=this._onRender.event,this._onSelectionChange=this._register(new Q),this.onSelectionChange=this._onSelectionChange.event,this._onTitleChange=this._register(new Q),this.onTitleChange=this._onTitleChange.event,this._onBell=this._register(new Q),this.onBell=this._onBell.event,this._onFocus=this._register(new Q),this._onBlur=this._register(new Q),this._onA11yCharEmitter=this._register(new Q),this._onA11yTabEmitter=this._register(new Q),this._onWillOpen=this._register(new Q),this._setup(),this._decorationService=this._instantiationService.createInstance(FW),this._instantiationService.setService(VL,this._decorationService),this._linkProviderService=this._instantiationService.createInstance(XV),this._instantiationService.setService(ZL,this._linkProviderService),this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(HL)),this._register(this._inputHandler.onRequestBell(()=>this._onBell.fire())),this._register(this._inputHandler.onRequestRefreshRows(e=>this.refresh(e?.start??0,e?.end??this.rows-1))),this._register(this._inputHandler.onRequestSendFocus(()=>this._reportFocus())),this._register(this._inputHandler.onRequestReset(()=>this.reset())),this._register(this._inputHandler.onRequestWindowsOptionsReport(e=>this._reportWindowsOptions(e))),this._register(this._inputHandler.onColor(e=>this._handleColorEvent(e))),this._register(kR.forward(this._inputHandler.onCursorMove,this._onCursorMove)),this._register(kR.forward(this._inputHandler.onTitleChange,this._onTitleChange)),this._register(kR.forward(this._inputHandler.onA11yChar,this._onA11yCharEmitter)),this._register(kR.forward(this._inputHandler.onA11yTab,this._onA11yTabEmitter)),this._register(this._bufferService.onResize(e=>this._afterResize(e.cols,e.rows))),this._register(vR(()=>{this._customKeyEventHandler=void 0,this.element?.parentNode?.removeChild(this.element)}))}get linkifier(){return this._linkifier.value}get onFocus(){return this._onFocus.event}get onBlur(){return this._onBlur.event}get onA11yChar(){return this._onA11yCharEmitter.event}get onA11yTab(){return this._onA11yTabEmitter.event}get onWillOpen(){return this._onWillOpen.event}_handleColorEvent(e){if(this._themeService)for(let t of e){let e,n=``;switch(t.index){case 256:e=`foreground`,n=`10`;break;case 257:e=`background`,n=`11`;break;case 258:e=`cursor`,n=`12`;break;default:e=`ansi`,n=`4;`+t.index}switch(t.type){case 0:let r=vV.toColorRGB(e===`ansi`?this._themeService.colors.ansi[t.index]:this._themeService.colors[e]);this.coreService.triggerDataEvent(`${$.ESC}]${n};${fW(r)}${uV.ST}`);break;case 1:if(e===`ansi`)this._themeService.modifyColors(e=>e.ansi[t.index]=_V.toColor(...t.color));else{let n=e;this._themeService.modifyColors(e=>e[n]=_V.toColor(...t.color))}break;case 2:this._themeService.restoreColor(t.index)}}}_setup(){super._setup(),this._customKeyEventHandler=void 0}get buffer(){return this.buffers.active}focus(){this.textarea&&this.textarea.focus({preventScroll:!0})}_handleScreenReaderModeOptionChange(e){e?!this._accessibilityManager.value&&this._renderService&&(this._accessibilityManager.value=this._instantiationService.createInstance(BW,this)):this._accessibilityManager.clear()}_handleTextAreaFocus(e){this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent($.ESC+`[I`),this.element.classList.add(`focus`),this._showCursor(),this._onFocus.fire()}blur(){return this.textarea?.blur()}_handleTextAreaBlur(){this.textarea.value=``,this.refresh(this.buffer.y,this.buffer.y),this.coreService.decPrivateModes.sendFocus&&this.coreService.triggerDataEvent($.ESC+`[O`),this.element.classList.remove(`focus`),this._onBlur.fire()}_syncTextArea(){if(!this.textarea||!this.buffer.isCursorInViewport||this._compositionHelper.isComposing||!this._renderService)return;let e=this.buffer.ybase+this.buffer.y,t=this.buffer.lines.get(e);if(!t)return;let n=Math.min(this.buffer.x,this.cols-1),r=this._renderService.dimensions.css.cell.height,i=t.getWidth(n),a=this._renderService.dimensions.css.cell.width*i,o=this.buffer.y*this._renderService.dimensions.css.cell.height,s=n*this._renderService.dimensions.css.cell.width;this.textarea.style.left=s+`px`,this.textarea.style.top=o+`px`,this.textarea.style.width=a+`px`,this.textarea.style.height=r+`px`,this.textarea.style.lineHeight=r+`px`,this.textarea.style.zIndex=`-5`}_initGlobal(){this._bindKeys(),this._register(fB(this.element,`copy`,e=>{this.hasSelection()&&fL(e,this._selectionService)}));let e=e=>pL(e,this.textarea,this.coreService,this.optionsService);this._register(fB(this.textarea,`paste`,e)),this._register(fB(this.element,`paste`,e)),aH?this._register(fB(this.element,`mousedown`,e=>{e.button===2&&gL(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})):this._register(fB(this.element,`contextmenu`,e=>{gL(e,this.textarea,this.screenElement,this._selectionService,this.options.rightClickSelectsWord)})),pH&&this._register(fB(this.element,`auxclick`,e=>{e.button===1&&hL(e,this.textarea,this.screenElement)}))}_bindKeys(){this._register(fB(this.textarea,`keyup`,e=>this._keyUp(e),!0)),this._register(fB(this.textarea,`keydown`,e=>this._keyDown(e),!0)),this._register(fB(this.textarea,`keypress`,e=>this._keyPress(e),!0)),this._register(fB(this.textarea,`compositionstart`,()=>this._compositionHelper.compositionstart())),this._register(fB(this.textarea,`compositionupdate`,e=>this._compositionHelper.compositionupdate(e))),this._register(fB(this.textarea,`compositionend`,()=>this._compositionHelper.compositionend())),this._register(fB(this.textarea,`input`,e=>this._inputEvent(e),!0)),this._register(this.onRender(()=>this._compositionHelper.updateCompositionElements()))}open(e){if(!e)throw Error(`Terminal requires a parent element.`);if(e.isConnected||this._logService.debug(`Terminal.open was called on an element that was not attached to the DOM`),this.element?.ownerDocument.defaultView&&this._coreBrowserService){this.element.ownerDocument.defaultView!==this._coreBrowserService.window&&(this._coreBrowserService.window=this.element.ownerDocument.defaultView);return}this._document=e.ownerDocument,this.options.documentOverride&&this.options.documentOverride instanceof Document&&(this._document=this.optionsService.rawOptions.documentOverride),this.element=this._document.createElement(`div`),this.element.dir=`ltr`,this.element.classList.add(`terminal`),this.element.classList.add(`xterm`),e.appendChild(this.element);let t=this._document.createDocumentFragment();this._viewportElement=this._document.createElement(`div`),this._viewportElement.classList.add(`xterm-viewport`),t.appendChild(this._viewportElement),this.screenElement=this._document.createElement(`div`),this.screenElement.classList.add(`xterm-screen`),this._register(fB(this.screenElement,`mousemove`,e=>this.updateCursorStyle(e))),this._helperContainer=this._document.createElement(`div`),this._helperContainer.classList.add(`xterm-helpers`),this.screenElement.appendChild(this._helperContainer),t.appendChild(this.screenElement);let n=this.textarea=this._document.createElement(`textarea`);this.textarea.classList.add(`xterm-helper-textarea`),this.textarea.setAttribute(`aria-label`,sL.get()),mH||this.textarea.setAttribute(`aria-multiline`,`false`),this.textarea.setAttribute(`autocorrect`,`off`),this.textarea.setAttribute(`autocapitalize`,`off`),this.textarea.setAttribute(`spellcheck`,`false`),this.textarea.tabIndex=0,this._register(this.optionsService.onSpecificOptionChange(`disableStdin`,()=>n.readOnly=this.optionsService.rawOptions.disableStdin)),this.textarea.readOnly=this.optionsService.rawOptions.disableStdin,this._coreBrowserService=this._register(this._instantiationService.createInstance(JV,this.textarea,e.ownerDocument.defaultView??window,this._document??typeof window<`u`?window.document:null)),this._instantiationService.setService(GL,this._coreBrowserService),this._register(fB(this.textarea,`focus`,e=>this._handleTextAreaFocus(e))),this._register(fB(this.textarea,`blur`,()=>this._handleTextAreaBlur())),this._helperContainer.appendChild(this.textarea),this._charSizeService=this._instantiationService.createInstance(WV,this._document,this._helperContainer),this._instantiationService.setService(WL,this._charSizeService),this._themeService=this._instantiationService.createInstance(QH),this._instantiationService.setService(XL,this._themeService),this._characterJoinerService=this._instantiationService.createInstance(TV),this._instantiationService.setService(YL,this._characterJoinerService),this._renderService=this._register(this._instantiationService.createInstance(bH,this.rows,this.screenElement)),this._instantiationService.setService(qL,this._renderService),this._register(this._renderService.onRenderedViewportChange(e=>this._onRender.fire(e))),this.onResize(e=>this._renderService.resize(e.cols,e.rows)),this._compositionView=this._document.createElement(`div`),this._compositionView.classList.add(`composition-view`),this._compositionHelper=this._instantiationService.createInstance(dV,this.textarea,this._compositionView),this._helperContainer.appendChild(this._compositionView),this._mouseService=this._instantiationService.createInstance($V),this._instantiationService.setService(KL,this._mouseService);let r=this._linkifier.value=this._register(this._instantiationService.createInstance(VW,this.screenElement));this.element.appendChild(t);try{this._onWillOpen.fire(this.element)}catch{}this._renderService.hasRenderer()||this._renderService.setRenderer(this._createRenderer()),this._register(this.onCursorMove(()=>{this._renderService.handleCursorMove(),this._syncTextArea()})),this._register(this.onResize(()=>this._renderService.handleResize(this.cols,this.rows))),this._register(this.onBlur(()=>this._renderService.handleBlur())),this._register(this.onFocus(()=>this._renderService.handleFocus())),this._viewport=this._register(this._instantiationService.createInstance(nV,this.element,this.screenElement)),this._register(this._viewport.onRequestScrollLines(e=>{super.scrollLines(e,!1),this.refresh(0,this.rows-1)})),this._selectionService=this._register(this._instantiationService.createInstance(HH,this.element,this.screenElement,r)),this._instantiationService.setService(JL,this._selectionService),this._register(this._selectionService.onRequestScrollLines(e=>this.scrollLines(e.amount,e.suppressScrollEvent))),this._register(this._selectionService.onSelectionChange(()=>this._onSelectionChange.fire())),this._register(this._selectionService.onRequestRedraw(e=>this._renderService.handleSelectionChanged(e.start,e.end,e.columnSelectMode))),this._register(this._selectionService.onLinuxMouseSelection(e=>{this.textarea.value=e,this.textarea.focus(),this.textarea.select()})),this._register(kR.any(this._onScroll.event,this._inputHandler.onScroll)(()=>{this._selectionService.refresh(),this._viewport?.queueSync()})),this._register(this._instantiationService.createInstance(rV,this.screenElement)),this._register(fB(this.element,`mousedown`,e=>this._selectionService.handleMouseDown(e))),this.coreMouseService.areMouseEventsActive?(this._selectionService.disable(),this.element.classList.add(`enable-mouse-events`)):this._selectionService.enable(),this.options.screenReaderMode&&(this._accessibilityManager.value=this._instantiationService.createInstance(BW,this)),this._register(this.optionsService.onSpecificOptionChange(`screenReaderMode`,e=>this._handleScreenReaderModeOptionChange(e))),this.options.overviewRuler.width&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(cV,this._viewportElement,this.screenElement))),this.optionsService.onSpecificOptionChange(`overviewRuler`,e=>{!this._overviewRulerRenderer&&e&&this._viewportElement&&this.screenElement&&(this._overviewRulerRenderer=this._register(this._instantiationService.createInstance(cV,this._viewportElement,this.screenElement)))}),this._charSizeService.measure(),this.refresh(0,this.rows-1),this._initGlobal(),this.bindMouse()}_createRenderer(){return this._instantiationService.createInstance(UV,this,this._document,this.element,this.screenElement,this._viewportElement,this._helperContainer,this.linkifier)}bindMouse(){let e=this,t=this.element;function n(t){let n=e._mouseService.getMouseReportCoords(t,e.screenElement);if(!n)return!1;let r,i;switch(t.overrideType||t.type){case`mousemove`:i=32,t.buttons===void 0?(r=3,t.button!==void 0&&(r=t.button<3?t.button:3)):r=t.buttons&1?0:t.buttons&4?1:t.buttons&2?2:3;break;case`mouseup`:i=0,r=t.button<3?t.button:3;break;case`mousedown`:i=1,r=t.button<3?t.button:3;break;case`wheel`:if(e._customWheelEventHandler&&e._customWheelEventHandler(t)===!1)return!1;let n=t.deltaY;if(n===0||e.coreMouseService.consumeWheelEvent(t,e._renderService?.dimensions?.device?.cell?.height,e._coreBrowserService?.dpr)===0)return!1;i=n<0?0:1,r=4;break;default:return!1}return i===void 0||r===void 0||r>4?!1:e.coreMouseService.triggerMouseEvent({col:n.col,row:n.row,x:n.x,y:n.y,button:r,action:i,ctrl:t.ctrlKey,alt:t.altKey,shift:t.shiftKey})}let r={mouseup:null,wheel:null,mousedrag:null,mousemove:null},i={mouseup:e=>(n(e),e.buttons||(this._document.removeEventListener(`mouseup`,r.mouseup),r.mousedrag&&this._document.removeEventListener(`mousemove`,r.mousedrag)),this.cancel(e)),wheel:e=>(n(e),this.cancel(e,!0)),mousedrag:e=>{e.buttons&&n(e)},mousemove:e=>{e.buttons||n(e)}};this._register(this.coreMouseService.onProtocolChange(e=>{e?(this.optionsService.rawOptions.logLevel===`debug`&&this._logService.debug(`Binding to mouse events:`,this.coreMouseService.explainEvents(e)),this.element.classList.add(`enable-mouse-events`),this._selectionService.disable()):(this._logService.debug(`Unbinding from mouse events.`),this.element.classList.remove(`enable-mouse-events`),this._selectionService.enable()),e&8?r.mousemove||=(t.addEventListener(`mousemove`,i.mousemove),i.mousemove):(t.removeEventListener(`mousemove`,r.mousemove),r.mousemove=null),e&16?r.wheel||=(t.addEventListener(`wheel`,i.wheel,{passive:!1}),i.wheel):(t.removeEventListener(`wheel`,r.wheel),r.wheel=null),e&2?r.mouseup||=i.mouseup:(this._document.removeEventListener(`mouseup`,r.mouseup),r.mouseup=null),e&4?r.mousedrag||=i.mousedrag:(this._document.removeEventListener(`mousemove`,r.mousedrag),r.mousedrag=null)})),this.coreMouseService.activeProtocol=this.coreMouseService.activeProtocol,this._register(fB(t,`mousedown`,e=>{if(e.preventDefault(),this.focus(),!(!this.coreMouseService.areMouseEventsActive||this._selectionService.shouldForceSelection(e)))return n(e),r.mouseup&&this._document.addEventListener(`mouseup`,r.mouseup),r.mousedrag&&this._document.addEventListener(`mousemove`,r.mousedrag),this.cancel(e)})),this._register(fB(t,`wheel`,t=>{if(!r.wheel){if(this._customWheelEventHandler&&this._customWheelEventHandler(t)===!1)return!1;if(!this.buffer.hasScrollback){if(t.deltaY===0)return!1;if(e.coreMouseService.consumeWheelEvent(t,e._renderService?.dimensions?.device?.cell?.height,e._coreBrowserService?.dpr)===0)return this.cancel(t,!0);let n=$.ESC+(this.coreService.decPrivateModes.applicationCursorKeys?`O`:`[`)+(t.deltaY<0?`A`:`B`);return this.coreService.triggerDataEvent(n,!0),this.cancel(t,!0)}}},{passive:!1}))}refresh(e,t){this._renderService?.refreshRows(e,t)}updateCursorStyle(e){this._selectionService?.shouldColumnSelect(e)?this.element.classList.add(`column-select`):this.element.classList.remove(`column-select`)}_showCursor(){this.coreService.isCursorInitialized||(this.coreService.isCursorInitialized=!0,this.refresh(this.buffer.y,this.buffer.y))}scrollLines(e,t){this._viewport?this._viewport.scrollLines(e):super.scrollLines(e,t),this.refresh(0,this.rows-1)}scrollPages(e){this.scrollLines(e*(this.rows-1))}scrollToTop(){this.scrollLines(-this._bufferService.buffer.ydisp)}scrollToBottom(e){e&&this._viewport?this._viewport.scrollToLine(this.buffer.ybase,!0):this.scrollLines(this._bufferService.buffer.ybase-this._bufferService.buffer.ydisp)}scrollToLine(e){let t=e-this._bufferService.buffer.ydisp;t!==0&&this.scrollLines(t)}paste(e){mL(e,this.textarea,this.coreService,this.optionsService)}attachCustomKeyEventHandler(e){this._customKeyEventHandler=e}attachCustomWheelEventHandler(e){this._customWheelEventHandler=e}registerLinkProvider(e){return this._linkProviderService.registerLinkProvider(e)}registerCharacterJoiner(e){if(!this._characterJoinerService)throw Error(`Terminal must be opened first`);let t=this._characterJoinerService.register(e);return this.refresh(0,this.rows-1),t}deregisterCharacterJoiner(e){if(!this._characterJoinerService)throw Error(`Terminal must be opened first`);this._characterJoinerService.deregister(e)&&this.refresh(0,this.rows-1)}get markers(){return this.buffer.markers}registerMarker(e){return this.buffer.addMarker(this.buffer.ybase+this.buffer.y+e)}registerDecoration(e){return this._decorationService.registerDecoration(e)}hasSelection(){return this._selectionService?this._selectionService.hasSelection:!1}select(e,t,n){this._selectionService.setSelection(e,t,n)}getSelection(){return this._selectionService?this._selectionService.selectionText:``}getSelectionPosition(){if(!(!this._selectionService||!this._selectionService.hasSelection))return{start:{x:this._selectionService.selectionStart[0],y:this._selectionService.selectionStart[1]},end:{x:this._selectionService.selectionEnd[0],y:this._selectionService.selectionEnd[1]}}}clearSelection(){this._selectionService?.clearSelection()}selectAll(){this._selectionService?.selectAll()}selectLines(e,t){this._selectionService?.selectLines(e,t)}_keyDown(e){if(this._keyDownHandled=!1,this._keyDownSeen=!0,this._customKeyEventHandler&&this._customKeyEventHandler(e)===!1)return!1;let t=this.browser.isMac&&this.options.macOptionIsMeta&&e.altKey;if(!t&&!this._compositionHelper.keydown(e))return this.options.scrollOnUserInput&&this.buffer.ybase!==this.buffer.ydisp&&this.scrollToBottom(!0),!1;!t&&(e.key===`Dead`||e.key===`AltGraph`)&&(this._unprocessedDeadKey=!0);let n=AW(e,this.coreService.decPrivateModes.applicationCursorKeys,this.browser.isMac,this.options.macOptionIsMeta);if(this.updateCursorStyle(e),n.type===3||n.type===2){let t=this.rows-1;return this.scrollLines(n.type===2?-t:t),this.cancel(e,!0)}if(n.type===1&&this.selectAll(),this._isThirdLevelShift(this.browser,e)||(n.cancel&&this.cancel(e,!0),!n.key)||e.key&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&e.key.length===1&&e.key.charCodeAt(0)>=65&&e.key.charCodeAt(0)<=90)return!0;if(this._unprocessedDeadKey)return this._unprocessedDeadKey=!1,!0;if((n.key===$.ETX||n.key===$.CR)&&(this.textarea.value=``),this._onKey.fire({key:n.key,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(n.key,!0),!this.optionsService.rawOptions.screenReaderMode||e.altKey||e.ctrlKey)return this.cancel(e,!0);this._keyDownHandled=!0}_isThirdLevelShift(e,t){let n=e.isMac&&!this.options.macOptionIsMeta&&t.altKey&&!t.ctrlKey&&!t.metaKey||e.isWindows&&t.altKey&&t.ctrlKey&&!t.metaKey||e.isWindows&&t.getModifierState(`AltGraph`);return t.type===`keypress`?n:n&&(!t.keyCode||t.keyCode>47)}_keyUp(e){this._keyDownSeen=!1,!(this._customKeyEventHandler&&this._customKeyEventHandler(e)===!1)&&(WW(e)||this.focus(),this.updateCursorStyle(e),this._keyPressHandled=!1)}_keyPress(e){let t;if(this._keyPressHandled=!1,this._keyDownHandled||this._customKeyEventHandler&&this._customKeyEventHandler(e)===!1)return!1;if(this.cancel(e),e.charCode)t=e.charCode;else if(e.which===null||e.which===void 0)t=e.keyCode;else if(e.which!==0&&e.charCode!==0)t=e.which;else return!1;return!t||(e.altKey||e.ctrlKey||e.metaKey)&&!this._isThirdLevelShift(this.browser,e)?!1:(t=String.fromCharCode(t),this._onKey.fire({key:t,domEvent:e}),this._showCursor(),this.coreService.triggerDataEvent(t,!0),this._keyPressHandled=!0,this._unprocessedDeadKey=!1,!0)}_inputEvent(e){if(e.data&&e.inputType===`insertText`&&(!e.composed||!this._keyDownSeen)&&!this.optionsService.rawOptions.screenReaderMode){if(this._keyPressHandled)return!1;this._unprocessedDeadKey=!1;let t=e.data;return this.coreService.triggerDataEvent(t,!0),this.cancel(e),!0}return!1}resize(e,t){if(e===this.cols&&t===this.rows){this._charSizeService&&!this._charSizeService.hasValidSize&&this._charSizeService.measure();return}super.resize(e,t)}_afterResize(e,t){this._charSizeService?.measure()}clear(){if(this.buffer.ybase!==0||this.buffer.y!==0){this.buffer.clearAllMarkers(),this.buffer.lines.set(0,this.buffer.lines.get(this.buffer.ybase+this.buffer.y)),this.buffer.lines.length=1,this.buffer.ydisp=0,this.buffer.ybase=0,this.buffer.y=0;for(let e=1;e<this.rows;e++)this.buffer.lines.push(this.buffer.getBlankLine(cU));this._onScroll.fire({position:this.buffer.ydisp}),this.refresh(0,this.rows-1)}}reset(){this.options.rows=this.rows,this.options.cols=this.cols;let e=this._customKeyEventHandler;this._setup(),super.reset(),this._selectionService?.reset(),this._decorationService.reset(),this._customKeyEventHandler=e,this.refresh(0,this.rows-1)}clearTextureAtlas(){this._renderService?.clearTextureAtlas()}_reportFocus(){this.element?.classList.contains(`focus`)?this.coreService.triggerDataEvent($.ESC+`[I`):this.coreService.triggerDataEvent($.ESC+`[O`)}_reportWindowsOptions(e){if(this._renderService)switch(e){case 0:let e=this._renderService.dimensions.css.canvas.width.toFixed(0),t=this._renderService.dimensions.css.canvas.height.toFixed(0);this.coreService.triggerDataEvent(`${$.ESC}[4;${t};${e}t`);break;case 1:let n=this._renderService.dimensions.css.cell.width.toFixed(0),r=this._renderService.dimensions.css.cell.height.toFixed(0);this.coreService.triggerDataEvent(`${$.ESC}[6;${r};${n}t`);break}}cancel(e,t){if(!(!this.options.cancelEvents&&!t))return e.preventDefault(),e.stopPropagation(),!1}};function WW(e){return e.keyCode===16||e.keyCode===17||e.keyCode===18}var GW=class{constructor(){this._addons=[]}dispose(){for(let e=this._addons.length-1;e>=0;e--)this._addons[e].instance.dispose()}loadAddon(e,t){let n={instance:t,dispose:t.dispose,isDisposed:!1};this._addons.push(n),t.dispose=()=>this._wrappedAddonDispose(n),t.activate(e)}_wrappedAddonDispose(e){if(e.isDisposed)return;let t=-1;for(let n=0;n<this._addons.length;n++)if(this._addons[n]===e){t=n;break}if(t===-1)throw Error(`Could not dispose an addon that has not been loaded`);e.isDisposed=!0,e.dispose.apply(e.instance),this._addons.splice(t,1)}},KW=class{constructor(e){this._line=e}get isWrapped(){return this._line.isWrapped}get length(){return this._line.length}getCell(e,t){if(!(e<0||e>=this._line.length))return t?(this._line.loadCell(e,t),t):this._line.loadCell(e,new TL)}translateToString(e,t,n){return this._line.translateToString(e,t,n)}},qW=class{constructor(e,t){this._buffer=e,this.type=t}init(e){return this._buffer=e,this}get cursorY(){return this._buffer.y}get cursorX(){return this._buffer.x}get viewportY(){return this._buffer.ydisp}get baseY(){return this._buffer.ybase}get length(){return this._buffer.lines.length}getLine(e){let t=this._buffer.lines.get(e);if(t)return new KW(t)}getNullCell(){return new TL}},JW=class extends xR{constructor(e){super(),this._core=e,this._onBufferChange=this._register(new Q),this.onBufferChange=this._onBufferChange.event,this._normal=new qW(this._core.buffers.normal,`normal`),this._alternate=new qW(this._core.buffers.alt,`alternate`),this._core.buffers.onBufferActivate(()=>this._onBufferChange.fire(this.active))}get active(){if(this._core.buffers.active===this._core.buffers.normal)return this.normal;if(this._core.buffers.active===this._core.buffers.alt)return this.alternate;throw Error(`Active buffer is neither normal nor alternate`)}get normal(){return this._normal.init(this._core.buffers.normal)}get alternate(){return this._alternate.init(this._core.buffers.alt)}},YW=class{constructor(e){this._core=e}registerCsiHandler(e,t){return this._core.registerCsiHandler(e,e=>t(e.toArray()))}addCsiHandler(e,t){return this.registerCsiHandler(e,t)}registerDcsHandler(e,t){return this._core.registerDcsHandler(e,(e,n)=>t(e,n.toArray()))}addDcsHandler(e,t){return this.registerDcsHandler(e,t)}registerEscHandler(e,t){return this._core.registerEscHandler(e,t)}addEscHandler(e,t){return this.registerEscHandler(e,t)}registerOscHandler(e,t){return this._core.registerOscHandler(e,t)}addOscHandler(e,t){return this.registerOscHandler(e,t)}},XW=class{constructor(e){this._core=e}register(e){this._core.unicodeService.register(e)}get versions(){return this._core.unicodeService.versions}get activeVersion(){return this._core.unicodeService.activeVersion}set activeVersion(e){this._core.unicodeService.activeVersion=e}},ZW=[`cols`,`rows`],QW=0,$W=class extends xR{constructor(e){super(),this._core=this._register(new UW(e)),this._addonManager=this._register(new GW),this._publicOptions={...this._core.options};let t=e=>this._core.options[e],n=(e,t)=>{this._checkReadonlyOptions(e),this._core.options[e]=t};for(let e in this._core.options){let r={get:t.bind(this,e),set:n.bind(this,e)};Object.defineProperty(this._publicOptions,e,r)}}_checkReadonlyOptions(e){if(ZW.includes(e))throw Error(`Option "${e}" can only be set in the constructor`)}_checkProposedApi(){if(!this._core.optionsService.rawOptions.allowProposedApi)throw Error(`You must set the allowProposedApi option to true to use proposed API`)}get onBell(){return this._core.onBell}get onBinary(){return this._core.onBinary}get onCursorMove(){return this._core.onCursorMove}get onData(){return this._core.onData}get onKey(){return this._core.onKey}get onLineFeed(){return this._core.onLineFeed}get onRender(){return this._core.onRender}get onResize(){return this._core.onResize}get onScroll(){return this._core.onScroll}get onSelectionChange(){return this._core.onSelectionChange}get onTitleChange(){return this._core.onTitleChange}get onWriteParsed(){return this._core.onWriteParsed}get element(){return this._core.element}get parser(){return this._parser||=new YW(this._core),this._parser}get unicode(){return this._checkProposedApi(),new XW(this._core)}get textarea(){return this._core.textarea}get rows(){return this._core.rows}get cols(){return this._core.cols}get buffer(){return this._buffer||=this._register(new JW(this._core)),this._buffer}get markers(){return this._checkProposedApi(),this._core.markers}get modes(){let e=this._core.coreService.decPrivateModes,t=`none`;switch(this._core.coreMouseService.activeProtocol){case`X10`:t=`x10`;break;case`VT200`:t=`vt200`;break;case`DRAG`:t=`drag`;break;case`ANY`:t=`any`}return{applicationCursorKeysMode:e.applicationCursorKeys,applicationKeypadMode:e.applicationKeypad,bracketedPasteMode:e.bracketedPasteMode,insertMode:this._core.coreService.modes.insertMode,mouseTrackingMode:t,originMode:e.origin,reverseWraparoundMode:e.reverseWraparound,sendFocusMode:e.sendFocus,synchronizedOutputMode:e.synchronizedOutput,wraparoundMode:e.wraparound}}get options(){return this._publicOptions}set options(e){for(let t in e)this._publicOptions[t]=e[t]}blur(){this._core.blur()}focus(){this._core.focus()}input(e,t=!0){this._core.input(e,t)}resize(e,t){this._verifyIntegers(e,t),this._core.resize(e,t)}open(e){this._core.open(e)}attachCustomKeyEventHandler(e){this._core.attachCustomKeyEventHandler(e)}attachCustomWheelEventHandler(e){this._core.attachCustomWheelEventHandler(e)}registerLinkProvider(e){return this._core.registerLinkProvider(e)}registerCharacterJoiner(e){return this._checkProposedApi(),this._core.registerCharacterJoiner(e)}deregisterCharacterJoiner(e){this._checkProposedApi(),this._core.deregisterCharacterJoiner(e)}registerMarker(e=0){return this._verifyIntegers(e),this._core.registerMarker(e)}registerDecoration(e){return this._checkProposedApi(),this._verifyPositiveIntegers(e.x??0,e.width??0,e.height??0),this._core.registerDecoration(e)}hasSelection(){return this._core.hasSelection()}select(e,t,n){this._verifyIntegers(e,t,n),this._core.select(e,t,n)}getSelection(){return this._core.getSelection()}getSelectionPosition(){return this._core.getSelectionPosition()}clearSelection(){this._core.clearSelection()}selectAll(){this._core.selectAll()}selectLines(e,t){this._verifyIntegers(e,t),this._core.selectLines(e,t)}dispose(){super.dispose()}scrollLines(e){this._verifyIntegers(e),this._core.scrollLines(e)}scrollPages(e){this._verifyIntegers(e),this._core.scrollPages(e)}scrollToTop(){this._core.scrollToTop()}scrollToBottom(){this._core.scrollToBottom()}scrollToLine(e){this._verifyIntegers(e),this._core.scrollToLine(e)}clear(){this._core.clear()}write(e,t){this._core.write(e,t)}writeln(e,t){this._core.write(e),this._core.write(`\r
|
|
120
120
|
`,t)}paste(e){this._core.paste(e)}refresh(e,t){this._verifyIntegers(e,t),this._core.refresh(e,t)}reset(){this._core.reset()}clearTextureAtlas(){this._core.clearTextureAtlas()}loadAddon(e){this._addonManager.loadAddon(this,e)}static get strings(){return{get promptLabel(){return sL.get()},set promptLabel(e){sL.set(e)},get tooMuchOutput(){return lL.get()},set tooMuchOutput(e){lL.set(e)}}}_verifyIntegers(...e){for(QW of e)if(QW===1/0||isNaN(QW)||QW%1!=0)throw Error(`This API only accepts integers`)}_verifyPositiveIntegers(...e){for(QW of e)if(QW&&(QW===1/0||isNaN(QW)||QW%1!=0||QW<0))throw Error(`This API only accepts positive integers`)}},eG=2,tG=1,nG=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let t=this._terminal.options.scrollback===0?0:this._terminal.options.overviewRuler?.width||14,n=window.getComputedStyle(this._terminal.element.parentElement),r=parseInt(n.getPropertyValue(`height`)),i=Math.max(0,parseInt(n.getPropertyValue(`width`))),a=window.getComputedStyle(this._terminal.element),o={top:parseInt(a.getPropertyValue(`padding-top`)),bottom:parseInt(a.getPropertyValue(`padding-bottom`)),right:parseInt(a.getPropertyValue(`padding-right`)),left:parseInt(a.getPropertyValue(`padding-left`))},s=o.top+o.bottom,c=o.right+o.left,l=r-s,u=i-c-t;return{cols:Math.max(eG,Math.floor(u/e.css.cell.width)),rows:Math.max(tG,Math.floor(l/e.css.cell.height))}}},rG={background:`#101010`,foreground:`#e6e6e6`,cursor:`#9dbefe`,cursorAccent:`#101010`,selectionBackground:`rgba(157, 190, 254, 0.25)`,black:`#101010`,red:`#fc533a`,green:`#12c905`,yellow:`#fcd53a`,blue:`#9dbefe`,magenta:`#edb2f1`,cyan:`#94e2d5`,white:`#e6e6e6`,brightBlack:`#555555`,brightRed:`#ff8a77`,brightGreen:`#6bff5c`,brightYellow:`#ffe57a`,brightBlue:`#c6dcff`,brightMagenta:`#ffd3f8`,brightCyan:`#b9fff2`,brightWhite:`#ffffff`};function iG({ptyID:e,onClose:t,onError:n}){let r=(0,E.useRef)(null),i=(0,E.useRef)(null),a=(0,E.useRef)(null),o=(0,E.useRef)(null),s=(0,E.useRef)(e);s.current=e;let[c,l]=(0,E.useState)(!1),u=async()=>{if(!c){l(!0);try{await G.ptyDelete(e),a.current?.close()}catch(e){l(!1),n?.(e instanceof Error?e.message:String(e))}}};return(0,E.useEffect)(()=>{let e=r.current;if(!e)return;let c=new $W({fontFamily:`"JetBrainsMono Nerd Font Mono", monospace`,fontSize:13,lineHeight:1.3,cursorBlink:!0,theme:rG,scrollback:5e3}),l=new nG;c.loadAddon(l),c.open(e);try{l.fit()}catch{}i.current=c,o.current=l,c.focus();let u=()=>{try{l.fit()}catch{return}let e=c.cols>0&&c.rows>0?{cols:c.cols,rows:c.rows}:null;e&&G.ptyUpdate(s.current,{size:e}).catch(()=>{})},d=new ResizeObserver(u);d.observe(e);let f=null,p=!1,m=!1,h=async()=>{try{let e=await G.ptyConnectToken(s.current),r=`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/api/pty/${s.current}/connect?ticket=${e.data.ticket}`;if(p)return;f=new WebSocket(r),a.current=f,f.onopen=()=>u(),f.onmessage=e=>{typeof e.data==`string`?c.write(e.data):e.data instanceof Blob?e.data.arrayBuffer().then(e=>g(new Uint8Array(e),c)):g(new Uint8Array(e.data),c)},f.onclose=()=>{p||t()},f.onerror=()=>{n?.(`Terminal connection lost`)}}catch(e){n?.(e instanceof Error?e.message:String(e))}},g=(e,t)=>{if(e[0]===0){let t=new TextDecoder().decode(e.subarray(1));try{typeof JSON.parse(t).cursor==`number`&&!m&&(m=!0,u())}catch{}return}t.write(new Uint8Array(e))},_=c.onData(e=>{a.current?.readyState===WebSocket.OPEN&&a.current.send(e)});return h(),()=>{p=!0,_.dispose(),d.disconnect(),a.current?.close(),c.dispose(),i.current=null}},[e]),(0,R.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between border-b border-border px-3 py-1.5`,children:[(0,R.jsx)(`span`,{className:`truncate font-mono text-xs text-[var(--text-weak)]`,children:e}),(0,R.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,children:[(0,R.jsxs)(U,{variant:`ghost`,size:`sm`,onClick:()=>void u(),disabled:c,title:`Kill process`,"aria-label":`Kill terminal`,className:`text-[color:var(--surface-critical-strong)]`,children:[(0,R.jsx)(et,{}),`Kill`]}),(0,R.jsx)(U,{variant:`ghost`,size:`sm`,onClick:t,children:`Close`})]})]}),(0,R.jsx)(`div`,{ref:r,className:`min-h-0 flex-1 bg-[var(--background-base)] p-2`})]})}var aG=12e4,oG={running:`blue`,exited:`green`,timeout:`amber`,killed:`red`};function sG(e){let t=e.time.completed??Date.now(),n=Math.max(0,Math.floor((t-e.time.started)/1e3));if(n<60)return`${n}s`;let r=Math.floor(n/60);return r<60?`${r}m ${n%60}s`:`${Math.floor(r/60)}h ${r%60}m`}function cG({trigger:e}){let[t,n]=(0,E.useState)(!1),[r,i]=(0,E.useState)(`shell`),a=J(e=>e.shellPanelTick);return(0,E.useEffect)(()=>{a>0&&n(!0)},[a]),(0,R.jsxs)(Km,{open:t,onOpenChange:n,children:[e===void 0?(0,R.jsx)(qm,{asChild:!0,children:(0,R.jsxs)(U,{variant:`ghost`,size:`sm`,children:[(0,R.jsx)(tt,{}),`Shell`]})}):(0,R.jsx)(qm,{asChild:!0,children:e}),(0,R.jsxs)(Zm,{className:`flex max-h-[85vh] flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl md:max-w-3xl`,children:[(0,R.jsxs)(Qm,{className:`border-b border-(--border-weak-base) px-4 py-3`,children:[(0,R.jsxs)(eh,{className:`flex items-center gap-2`,children:[(0,R.jsx)(tt,{className:`size-4 text-(color:--text-interactive-base)`}),`Shell & Terminals`]}),(0,R.jsx)(th,{children:`Run shell commands and manage PTY sessions.`})]}),(0,R.jsxs)(Xx,{value:r,onValueChange:i,className:`flex min-h-0 flex-1 flex-col`,children:[(0,R.jsxs)(Qx,{variant:`line`,className:`mx-4 mt-3`,children:[(0,R.jsx)($x,{value:`shell`,children:`Shell`}),(0,R.jsx)($x,{value:`terminals`,children:`Terminals`})]}),(0,R.jsx)(eS,{value:`shell`,forceMount:!0,className:V(`min-h-0`,r!==`shell`&&`hidden`),children:(0,R.jsx)(lG,{active:r===`shell`})}),(0,R.jsx)(eS,{value:`terminals`,forceMount:!0,className:V(`min-h-0`,r!==`terminals`&&`hidden`),children:(0,R.jsx)(dG,{active:r===`terminals`})})]})]})]})}function lG({active:e}){let[t,n]=(0,E.useState)([]),[r,i]=(0,E.useState)(!0),[a,o]=(0,E.useState)(null),[s,c]=(0,E.useState)(``),[l,u]=(0,E.useState)(String(aG)),[d,f]=(0,E.useState)(!1),[p,m]=(0,E.useState)(null),[h,g]=(0,E.useState)({}),_=(0,E.useRef)({}),v=(0,E.useCallback)(async()=>{try{let e=await G.shellList();n(e.data),o(null)}catch(e){o(e instanceof Error?e.message:String(e))}finally{i(!1)}},[]);(0,E.useEffect)(()=>{if(e)return v(),og({name:`shell-panel-list`,minInterval:5e3,run:()=>v()})},[e,v]);let y=(0,E.useCallback)(async e=>{try{let t=(await G.shellOutput(e,{cursor:_.current[e]})).data,n=t.truncated||_.current[e]===void 0;g(r=>({...r,[e]:(n?``:r[e]??``)+t.output})),_.current[e]=t.cursor}catch{g(t=>({...t,[e]:(t[e]??``)+`
|
|
121
121
|
[output stream unavailable]`}))}},[]);(0,E.useEffect)(()=>{if(!e||!p)return;let n=t.find(e=>e.id===p);if(!(!n||n.status!==`running`))return og({name:`shell-panel-output`,minInterval:1200,run:()=>y(p)})},[e,p,t,y]);let b=async()=>{if(!(!s.trim()||d)){f(!0),o(null);try{let e=Number(l),t=await G.shellCreate({command:s.trim(),timeout:Number.isFinite(e)&&e>0?e:aG});c(``),await v(),m(t.data.id)}catch(e){o(e instanceof Error?e.message:String(e))}finally{f(!1)}}},x=async e=>{try{await G.shellDelete(e),g(t=>{let n={...t};return delete n[e],n}),delete _.current[e],p===e&&m(null),await v()}catch(e){o(e instanceof Error?e.message:String(e))}},S=async(e,t)=>{let n=Number(t);if(!(!Number.isFinite(n)||n<0))try{await G.shellTimeout(e,n),await v()}catch(e){o(e instanceof Error?e.message:String(e))}};return(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-3 p-4`,children:[(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(nh,{value:s,onChange:e=>c(e.target.value),onKeyDown:e=>{e.key===`Enter`&&b()},placeholder:`command to run`,className:`flex-1 font-mono text-xs`}),(0,R.jsx)(nh,{value:l,onChange:e=>u(e.target.value),onKeyDown:e=>{e.key===`Enter`&&b()},placeholder:`timeout ms`,title:`Timeout in milliseconds`,className:`w-24 font-mono text-xs`}),(0,R.jsxs)(U,{onClick:()=>void b(),disabled:!s.trim()||d,children:[(0,R.jsx)(Be,{}),`Run`]}),(0,R.jsx)(U,{variant:`ghost`,size:`icon`,title:`Refresh`,onClick:()=>void v(),children:(0,R.jsx)(Ke,{})})]}),a&&(0,R.jsx)(`p`,{className:`text-xs text-(color:--surface-critical-strong)`,children:a}),(0,R.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto`,children:r?(0,R.jsxs)(`div`,{className:`flex items-center gap-2 px-1 py-2 text-xs text-(color:--text-weaker)`,children:[(0,R.jsx)(uS,{}),` Loading shells…`]}):t.length===0?(0,R.jsx)(`p`,{className:`px-1 py-2 text-xs text-(color:--text-weaker)`,children:`No shell sessions yet — run a command above.`}):t.map(e=>(0,R.jsx)(uG,{shell:e,expanded:p===e.id,output:h[e.id]??``,onToggle:()=>{m(t=>t===e.id?null:e.id),_.current[e.id]||y(e.id)},onKill:()=>void x(e.id),onSetTimeout:t=>void S(e.id,t)},e.id))})]})}function uG({shell:e,expanded:t,output:n,onToggle:r,onKill:i,onSetTimeout:a}){let[o,s]=(0,E.useState)(``),c=(0,E.useRef)(null);return(0,E.useEffect)(()=>{let e=c.current;e&&(e.scrollTop=e.scrollHeight)},[n]),(0,R.jsxs)(`div`,{className:`rounded-md border border-(--border-weak-base) bg-(--surface-base)`,children:[(0,R.jsxs)(`div`,{className:`flex cursor-pointer items-center gap-2 px-2.5 py-1.5 hover:bg-(--surface-base-hover)`,onClick:r,children:[t?(0,R.jsx)(I,{className:`size-3.5 shrink-0 text-(color:--text-weaker)`}):(0,R.jsx)(L,{className:`size-3.5 shrink-0 text-(color:--text-weaker)`}),(0,R.jsx)(fS,{tone:oG[e.status],children:e.status}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-(color:--text-strong)`,children:e.command}),(0,R.jsx)(`span`,{className:`hidden max-w-40 truncate font-mono text-xs text-(color:--text-weaker) sm:inline`,children:e.cwd}),(0,R.jsxs)(`span`,{className:`shrink-0 text-xs text-(color:--text-weak)`,children:[mS(e.time.started),` · `,sG(e)]}),e.status===`running`&&(0,R.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:`Kill`,"aria-label":`Kill`,onClick:e=>{e.stopPropagation(),i()},className:`text-(color:--surface-critical-strong)`,children:(0,R.jsx)(et,{})})]}),t&&(0,R.jsxs)(`div`,{className:`flex flex-col gap-2 border-t border-(--border-weak-base) p-2.5`,children:[(0,R.jsx)(`pre`,{ref:c,className:V(`max-h-56 min-h-10 overflow-auto rounded-md border border-(--border-weak-base) bg-(--surface-inset-base) p-2 font-mono text-xs whitespace-pre-wrap text-(color:--text-base)`,!n&&`text-(color:--text-weaker)`),children:n||`No output yet…`}),(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(nt,{className:`size-3.5 text-(color:--text-weaker)`}),(0,R.jsx)(nh,{value:o,onChange:e=>s(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(a(o),s(``))},placeholder:`set timeout (ms)`,className:`h-6 w-36 font-mono text-xs`}),(0,R.jsx)(U,{variant:`ghost`,size:`xs`,disabled:!o.trim(),onClick:()=>{a(o),s(``)},children:`Apply`})]})]})]})}function dG({active:e}){let[t,n]=(0,E.useState)([]),[r,i]=(0,E.useState)(!0),[a,o]=(0,E.useState)(null),[s,c]=(0,E.useState)(``),[l,u]=(0,E.useState)(``),[d,f]=(0,E.useState)(``),[p,m]=(0,E.useState)(!1),[h,g]=(0,E.useState)({}),[_,v]=(0,E.useState)(Date.now()),[y,b]=(0,E.useState)(null),x=(0,E.useCallback)(async()=>{try{let e=await G.ptyList();n(e.data),o(null)}catch(e){o(e instanceof Error?e.message:String(e))}finally{i(!1)}},[]);(0,E.useEffect)(()=>{if(e)return x(),og({name:`pty-panel-list`,minInterval:5e3,run:()=>{x(),v(Date.now())}})},[e,x]);let S=async()=>{if(!(!l.trim()||p)){m(!0),o(null);try{await G.ptyCreate({command:l.trim(),cwd:d.trim()||void 0,title:s.trim()||void 0}),c(``),u(``),f(``),await x()}catch(e){o(e instanceof Error?e.message:String(e))}finally{m(!1)}}},C=async e=>{try{await G.ptyDelete(e),g(t=>{let n={...t};return delete n[e],n}),await x()}catch(e){o(e instanceof Error?e.message:String(e))}},w=async e=>{try{let t=await G.ptyConnectToken(e);g(n=>({...n,[e]:{kind:`connected`,ticket:t.data.ticket,expiresAt:Date.now()+t.data.expires_in*1e3}})),o(null)}catch(t){g(n=>({...n,[e]:{kind:`error`,message:t instanceof Error?t.message:String(t)}}))}};return(0,R.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-3 p-4`,children:y?(0,R.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:(0,R.jsx)(iG,{ptyID:y,onClose:()=>b(null),onError:e=>o(e)})}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(nh,{value:s,onChange:e=>c(e.target.value),onKeyDown:e=>{e.key===`Enter`&&S()},placeholder:`title`,className:`w-28 text-xs`}),(0,R.jsx)(nh,{value:l,onChange:e=>u(e.target.value),onKeyDown:e=>{e.key===`Enter`&&S()},placeholder:`command (e.g. bash)`,className:`flex-1 font-mono text-xs`}),(0,R.jsx)(nh,{value:d,onChange:e=>f(e.target.value),onKeyDown:e=>{e.key===`Enter`&&S()},placeholder:`cwd (optional)`,className:`w-36 font-mono text-xs`}),(0,R.jsxs)(U,{onClick:()=>void S(),disabled:!l.trim()||p,children:[(0,R.jsx)(tt,{}),`Create`]}),(0,R.jsx)(U,{variant:`ghost`,size:`icon`,title:`Refresh`,onClick:()=>void x(),children:(0,R.jsx)(Ke,{})})]}),a&&(0,R.jsx)(`p`,{className:`text-xs text-(color:--surface-critical-strong)`,children:a}),(0,R.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto`,children:r?(0,R.jsxs)(`div`,{className:`flex items-center gap-2 px-1 py-2 text-xs text-(color:--text-weaker)`,children:[(0,R.jsx)(uS,{}),` Loading terminals…`]}):t.length===0?(0,R.jsx)(`p`,{className:`px-1 py-2 text-xs text-(color:--text-weaker)`,children:`No PTY sessions yet — create one above.`}):t.map(e=>(0,R.jsx)(fG,{pty:e,connection:h[e.id],now:_,onConnect:()=>void w(e.id),onOpen:()=>b(e.id),onDelete:()=>void C(e.id)},e.id))}),(0,R.jsx)(tL,{className:`bg-(--border-weak-base)`}),(0,R.jsx)(`p`,{className:`text-xs text-(color:--text-weaker)`,children:`Live terminals stream over a websocket — open one to interact.`})]})})}function fG({pty:e,connection:t,now:n,onConnect:r,onOpen:i,onDelete:a}){let o=e.args.length>0?` ${e.args.join(` `)}`:``,s=t?.kind===`connected`?Math.max(0,Math.ceil((t.expiresAt-n)/1e3)):0;return(0,R.jsxs)(`div`,{className:`rounded-md border border-(--border-weak-base) bg-(--surface-base) px-2.5 py-2`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(fS,{tone:e.status===`running`?`blue`:`neutral`,children:e.status}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-(color:--text-strong)`,children:e.title||e.command}),(0,R.jsxs)(`span`,{className:`hidden shrink-0 text-xs text-(color:--text-weaker) md:inline`,children:[`pid `,e.pid,e.exitCode===void 0?``:` · exit ${e.exitCode}`]}),(0,R.jsxs)(U,{variant:`ghost`,size:`xs`,onClick:i,disabled:e.status!==`running`,children:[(0,R.jsx)($e,{}),`Open`]}),(0,R.jsxs)(U,{variant:`ghost`,size:`xs`,onClick:r,disabled:e.status!==`running`,children:[(0,R.jsx)(ie,{}),`Connect`]}),(0,R.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:e.status===`running`?`Kill`:`Delete`,"aria-label":e.status===`running`?`Kill terminal`:`Delete terminal record`,onClick:a,className:`text-(color:--surface-critical-strong)`,children:e.status===`running`?(0,R.jsx)(et,{}):(0,R.jsx)(rt,{})})]}),(0,R.jsxs)(`div`,{className:`mt-1 flex items-center gap-2 pl-5`,children:[(0,R.jsxs)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-(color:--text-weak)`,children:[e.command,o,e.cwd?` — ${e.cwd}`:``]}),t?.kind===`connected`?(0,R.jsxs)(`span`,{className:`flex shrink-0 items-center gap-1.5 text-xs`,children:[(0,R.jsx)(Ve,{className:`size-3 text-(color:--surface-success-strong)`}),(0,R.jsx)(fS,{tone:`green`,children:`connected`}),(0,R.jsxs)(`span`,{className:`hidden font-mono text-(color:--text-weaker) sm:inline`,children:[t.ticket.slice(0,10),`… · `,s,`s`]})]}):t?.kind===`error`?(0,R.jsx)(`span`,{className:`max-w-56 shrink-0 truncate`,title:t.message,children:(0,R.jsx)(fS,{tone:`red`,children:t.message})}):(0,R.jsx)(`span`,{className:`shrink-0 text-xs text-(color:--text-weaker)`,children:`disconnected`})]})]})}var pG=`fixed top-1/2 left-1/2 z-50 flex w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-2 rounded-lg border border-[var(--border-weak-base)] bg-[var(--surface-float-base)] p-4 text-sm text-popover-foreground duration-100 outline-none sm:max-w-lg data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,mG=`w-full rounded-md border border-[var(--border-base)] bg-[var(--input-base)] px-2.5 py-1.5 text-sm text-[var(--text-strong)] outline-none transition-colors placeholder:text-[var(--text-weaker)] focus:border-[var(--border-selected)]`,hG=`flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors text-[color:var(--text-base)] hover:bg-[color:var(--surface-base-hover)]`,gG=`flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors bg-[color:var(--surface-raised-base-active)] text-[color:var(--text-strong)]`;function _G(){return J(e=>e.splitPickerOpen)?(0,R.jsx)(vG,{}):null}function vG(){let e=J(e=>e.sessions),t=J(e=>e.panes),n=J(e=>e.running),r=J(e=>e.queued),i=J(e=>e.activeIDs),a=J(e=>e.currentSessionID&&!Eg(e.currentSessionID)?e.sessions.find(t=>t.id===e.currentSessionID)??e.sessionDetails[e.currentSessionID]:void 0),[o,s]=(0,E.useState)(`sessions`),[c,l]=(0,E.useState)(``),[u,d]=(0,E.useState)(0),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)([]),[g,_]=(0,E.useState)(!1),[v,y]=(0,E.useState)(null),[b,x]=(0,E.useState)(null),S=(0,E.useRef)(null),C=(0,E.useRef)(!1),w=(0,E.useMemo)(()=>new Set(t.map(e=>e.sessionID)),[t]),T=c.trim().toLowerCase(),D=(0,E.useMemo)(()=>e.filter(e=>!w.has(e.id)&&!e.parentID&&(!T||(e.title??``).toLowerCase().includes(T)||e.id.toLowerCase().includes(T)||e.location.directory.toLowerCase().includes(T))).sort((e,t)=>t.time.updated-e.time.updated),[e,w,T]),O=Math.min(u,Math.max(0,D.length-1));(0,E.useEffect)(()=>d(0),[T]);let k=a?.location?.directory;function A(){s(`workspace`),x(null),!C.current&&(C.current=!0,_(!0),Promise.all([G.locationInfo(),G.projectList()]).then(([e,t])=>{p(e),h(t)}).catch(()=>x(`Could not load workspaces`)).finally(()=>_(!1)))}function j(){s(`sessions`),x(null)}function M(e){Gv(e).then(e=>{e||x(`Already open in a pane, or no free slots`)})}async function N(e,t){if(!v){y(e),x(null);try{await Gv(await Jy(t))||x(`No free split slots`)}catch(e){x(e instanceof Error?e.message:String(e))}finally{y(null)}}}let te=(0,E.useMemo)(()=>{let e=new Set;for(let t of m)t.directory&&e.add(t.directory);return[...e]},[m]);return(0,R.jsx)(es,{open:!0,onOpenChange:e=>{e||Wv()},children:(0,R.jsxs)(os,{children:[(0,R.jsx)(cs,{className:`bg-black/60`}),(0,R.jsxs)(fs,{tabIndex:-1,"data-slot":`dialog-content`,className:pG,"aria-describedby":void 0,onOpenAutoFocus:e=>{e.preventDefault(),S.current?.focus()},children:[(0,R.jsxs)(_s,{className:`flex items-center gap-2 text-[var(--font-size-large)] font-medium text-[var(--text-strong)]`,children:[(0,R.jsx)(Qe,{className:`size-4 shrink-0 text-[var(--text-interactive-base)]`,"aria-hidden":!0}),`Split view`,(0,R.jsx)(`span`,{className:`truncate text-xs font-normal text-[var(--text-weaker)]`,children:`open a session beside this one`})]}),o===`sessions`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`input`,{ref:S,value:c,onChange:e=>l(e.target.value),onKeyDown:e=>{if(e.key===`ArrowDown`)e.preventDefault(),d(Math.min(O+1,D.length-1));else if(e.key===`ArrowUp`)e.preventDefault(),d(Math.max(O-1,0));else if(e.key===`Enter`){e.preventDefault();let t=D[O];t&&M(t.id)}},placeholder:`Filter sessions… (title, id, workspace)`,className:mG,autoComplete:`off`,spellCheck:!1}),(0,R.jsxs)(`button`,{type:`button`,onClick:A,disabled:v!==null,className:`flex w-full cursor-pointer items-center gap-2 rounded-md border border-dashed border-[var(--border-weak-base)] px-2 py-1.5 text-left text-sm text-[var(--text-weak)] transition-colors hover:border-[var(--border-selected)] hover:text-[var(--text-strong)] disabled:pointer-events-none disabled:opacity-50`,children:[(0,R.jsx)(He,{className:`size-3.5 shrink-0`}),`Start new session`]}),(0,R.jsx)(`div`,{className:`-mx-1 max-h-72 overflow-y-auto px-1`,children:D.length===0?(0,R.jsx)(`p`,{className:`px-2 py-6 text-center text-xs text-[var(--text-weaker)]`,children:T?`No matching sessions`:`Every session is already in a pane`}):D.map((e,t)=>(0,R.jsx)(bG,{title:e.title||`session ${e.id.slice(0,8)}…`,dir:e.location.directory,at:e.time.updated,running:!!n[e.id]||!!r[e.id]||i.includes(e.id),highlighted:t===O,onHover:()=>d(t),onPick:()=>M(e.id)},e.id))})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`button`,{type:`button`,onClick:j,className:`flex cursor-pointer items-center gap-1 self-start rounded-md px-1 py-0.5 text-xs text-[var(--text-weaker)] transition-colors hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(ee,{className:`size-3`}),` all sessions`]}),(0,R.jsx)(`div`,{className:`-mx-1 max-h-80 overflow-y-auto px-1`,children:g?(0,R.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-6 text-xs text-[var(--text-weaker)]`,children:[(0,R.jsx)(uS,{className:`size-3`}),` Loading workspaces…`]}):(0,R.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,R.jsx)(xG,{label:`Default workspace`,sub:f?.directory,busy:v==="default",disabled:v!==null,onChoose:()=>N(`default`,null)}),k&&a&&(0,R.jsx)(xG,{label:`same as ${a.title??`current session`}`,sub:k,busy:v===`focused`,disabled:v!==null,onChoose:()=>N(`focused`,k)}),te.map(e=>(0,R.jsx)(xG,{label:yG(e),sub:e,busy:v===e,disabled:v!==null,onChoose:()=>N(e,e)},e)),te.length===0&&!k&&(0,R.jsx)(`p`,{className:`px-2 py-4 text-center text-xs text-[var(--text-weaker)]`,children:`No workspaces`})]})})]}),b&&(0,R.jsx)(`p`,{className:`text-xs text-[var(--surface-critical-strong)]`,children:b}),(0,R.jsxs)(`p`,{className:`text-xs text-[var(--text-weaker)]`,children:[(0,R.jsx)(`span`,{className:`font-mono`,children:`↑↓`}),` select · `,(0,R.jsx)(`span`,{className:`font-mono`,children:`↵`}),` open ·`,` `,(0,R.jsx)(`span`,{className:`font-mono`,children:`esc`}),` close`]}),(0,R.jsx)(xs,{asChild:!0,children:(0,R.jsx)(`button`,{type:`button`,"aria-label":`Close`,className:`absolute top-2 right-2 flex size-7 cursor-pointer items-center justify-center rounded-md text-[var(--text-weaker)] transition-colors hover:bg-[color:var(--surface-base-hover)] hover:text-[var(--text-strong)]`,children:(0,R.jsx)(at,{className:`size-4`})})})]})]})})}function yG(e){let t=e.split(`/`).filter(Boolean);return t.length>0?t[t.length-1]:e}function bG({title:e,dir:t,at:n,running:r,highlighted:i,onHover:a,onPick:o}){let s=(0,E.useRef)(null);return(0,E.useEffect)(()=>{i&&s.current?.scrollIntoView({block:`nearest`})},[i]),(0,R.jsxs)(`button`,{ref:s,type:`button`,onMouseMove:a,onClick:o,title:t,className:i?gG:hG,children:[(0,R.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full ${r?`animate-pulse bg-emerald-500`:`bg-[color:var(--border-base)]`}`}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e}),(0,R.jsx)(`span`,{className:`max-w-44 shrink-0 truncate font-mono text-[10px] text-[var(--text-weaker)]`,children:t}),r&&(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-[var(--text-weaker)]`,children:`running`}),(0,R.jsx)(`span`,{className:`w-8 shrink-0 text-right font-mono text-[10px] text-[var(--text-weaker)]`,children:pS(n)})]})}function xG({label:e,sub:t,busy:n,disabled:r,onChoose:i}){return(0,R.jsxs)(`button`,{type:`button`,onClick:i,disabled:r,className:n?gG:hG,children:[n?(0,R.jsx)(uS,{className:`size-3.5 shrink-0`}):(0,R.jsx)(Ee,{className:`size-3.5 shrink-0 text-[var(--text-weaker)]`}),(0,R.jsx)(`span`,{className:`min-w-0 shrink truncate`,children:e}),t&&(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[10px] text-[var(--text-weaker)]`,children:t})]})}var SG=`webui.activityStrip.collapsed`,CG=15e3;function wG(e){return e?e.replace(/\/+$/,``).replace(/^\/(home|Users)\/[^/]+/,`~`):``}function TG(e){let t=Math.max(0,Math.floor((Date.now()-e)/1e3));if(t<60)return`${t}s`;let n=Math.floor(t/60),r=t%60;return r?`${n}m ${r}s`:`${n}m`}function EG(e){let t=e.name||`tool`;if(e.status===`streaming`&&e.inputText){let n=e.inputText.replace(/\s+/g,` `).trim().slice(0,80);return n?`${t} ${n}…`:t}let n=e.input;if(n){if(typeof n.path==`string`)return`${t} ${String(n.path).split(`/`).pop()}`;if(typeof n.command==`string`)return`${t} ${String(n.command).slice(0,48)}`;if(typeof n.pattern==`string`)return`${t} "${String(n.pattern).slice(0,32)}"`;if(typeof n.description==`string`)return`${t} ${n.description.slice(0,40)}`;if(typeof n.agent==`string`&&typeof n.description==`string`)return`${t} ${String(n.agent)} — ${String(n.description).slice(0,24)}`}if(e.inputText){try{let n=JSON.parse(e.inputText);if(typeof n.path==`string`)return`${t} ${String(n.path).split(`/`).pop()}`;if(typeof n.command==`string`)return`${t} ${String(n.command).slice(0,48)}`}catch{}let n=e.inputText.replace(/\s+/g,` `).trim().slice(0,80);if(n&&n!==`{}`&&n!==`[]`)return`${t} ${n}`}return t}function DG(e){document.querySelectorAll(`link[rel="stylesheet"], style`).forEach(t=>{e.document.head.appendChild(t.cloneNode(!0))});try{document.adoptedStyleSheets?.length&&(e.document.adoptedStyleSheets=document.adoptedStyleSheets)}catch{}}function OG({tool:e}){let t=e.status===`running`||e.status===`streaming`,n=e.status===`error`,r=n?`✗`:t?`⠋`:e.name===`subagent`?`→`:e.name===`shell`||e.name===`bash`?`$`:e.name===`edit`?`←`:`·`;return(0,R.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 truncate py-0.5 text-[11px] ${n?`text-[var(--surface-critical-strong)]`:t?`text-[var(--text-base)]`:`text-[var(--text-weak)]`}`,children:[(0,R.jsx)(`span`,{className:`w-3 shrink-0 text-center font-mono text-[10px] ${t?`animate-pulse`:``}`,children:t?`●`:r}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono`,children:EG(e)}),t&&(0,R.jsx)(`span`,{className:`size-1.5 shrink-0 animate-pulse rounded-full bg-emerald-500`,"aria-hidden":!0})]})}function kG({assistants:e}){if(e.length===0)return(0,R.jsx)(`span`,{className:`text-[11px] italic text-[var(--text-weaker)]`,children:`waiting…`});let t=e.flatMap(e=>e.content),n=t.filter(e=>e.type===`reasoning`).slice(-1),r=t.filter(e=>e.type===`text`).slice(-2),i=t.filter(e=>e.type===`tool`).slice(-6),a=i.filter(e=>e.tool.status===`running`||e.tool.status===`streaming`),o=[...i.filter(e=>e.tool.status!==`running`&&e.tool.status!==`streaming`).slice(-3),...a];return(0,R.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-0.5`,children:[n.length>0&&(0,R.jsx)(`div`,{className:`line-clamp-1 truncate text-[11px] italic text-[var(--text-weaker)]`,children:(()=>{let e=n[0].text.replace(/\s+/g,` `).trim();return`thought: ${e.length>140?`…${e.slice(-140)}`:e}`})()}),r.map(e=>{let t=e.text.replace(/\s+/g,` `).trim();if(!t)return null;let n=t.length>220?`…${t.slice(-220)}`:t;return(0,R.jsx)(`div`,{className:`line-clamp-2 break-words text-xs leading-snug text-[var(--text-base)]`,children:n},`t-${e.ordinal}`)}),o.map(e=>(0,R.jsx)(OG,{tool:e.tool},e.tool.id)),t.length===0&&(0,R.jsx)(`span`,{className:`text-[11px] text-[var(--text-weaker)]`,children:`working…`})]})}function AG({session:e,assistants:t,running:n,queued:r,onOpen:i}){let[a,o]=(0,E.useState)(0);(0,E.useEffect)(()=>{if(n)return og({name:`activity-row-elapsed`,minInterval:1e3,run:()=>o(e=>e+1)})},[n]);let s=t[0]?.started??e.time?.updated??Date.now(),c=n?`running`:r?`queued`:`idle`;return(0,R.jsxs)(`div`,{className:`group flex min-w-0 flex-col gap-1 rounded-md border border-[var(--border-weak-base)] bg-[var(--surface-base)] px-2 py-1.5 hover:border-[var(--border-base)]`,children:[(0,R.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,R.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full ${c===`running`?`bg-emerald-500 animate-pulse`:c===`queued`?`bg-amber-500 animate-pulse`:`bg-[var(--border-base)]`}`,"aria-hidden":!0}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs font-medium text-[var(--text-strong)]`,title:e.title??e.id,children:e.title||`Untitled session`}),e.location?.directory&&(0,R.jsx)(`span`,{className:`hidden max-w-[14ch] truncate font-mono text-[10px] text-[var(--text-weaker)] sm:inline`,title:e.location.directory,children:wG(e.location.directory)}),(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-[var(--text-weaker)]`,children:n?TG(s):r?`queued`:``}),(0,R.jsxs)(`button`,{type:`button`,onClick:()=>i(e.id),title:`Open session`,className:`inline-flex shrink-0 cursor-pointer items-center gap-1 rounded-md border border-transparent px-1 py-0.5 text-[11px] text-[var(--text-weaker)] hover:border-[var(--border-weak-base)] hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(pe,{className:`size-3`}),` open`]})]}),(0,R.jsx)(`div`,{className:`min-w-0 pl-3`,children:(0,R.jsx)(kG,{assistants:t})})]})}function jG({onOpen:e}){let t=J(e=>e.sessions),n=J(e=>e.running),r=J(e=>e.queued),i=J(e=>e.activeIDs),a=J(e=>e.live),o=(0,E.useMemo)(()=>{let e=new Map;for(let t of a){let n=e.get(t.sessionID)??[];n.push(t),e.set(t.sessionID,n)}for(let t of e.values())t.sort((e,t)=>e.started-t.started);return e},[a]),s=e=>n[e]||r[e]||(o.get(e)??[]).some(e=>e.finish===void 0)?!0:i.includes(e)&&Date.now()-Jg(e)<CG,c=(0,E.useMemo)(()=>{let e=t.filter(e=>!e.parentID),r=[];for(let n of e){let e=Ov(t,n.id).filter(e=>s(e.id)),i=s(n.id);(i||e.length>0)&&r.push({parent:n,parentLive:i,children:e})}let i=new Set(r.flatMap(e=>e.children.map(e=>e.id))),a=t.filter(e=>!!e.parentID&&s(e.id)&&!i.has(e.id));for(let e of a){let n=t.find(t=>t.id===e.parentID)??{id:e.parentID,title:`Parent`,time:{updated:0}};r.find(t=>t.parent.id===e.parentID)||r.push({parent:n,parentLive:!1,children:[e]})}return r.sort((e,t)=>{let r=e.parentLive&&n[e.parent.id]?1:+!!e.children.some(e=>!!n[e.id]),i=t.parentLive&&n[t.parent.id]?1:+!!t.children.some(e=>!!n[e.id]);return r===i?(t.parent.time?.updated??0)-(e.parent.time?.updated??0):i-r}),r},[t,n,r,i,a,o]);return c.length===0?(0,R.jsx)(`div`,{className:`px-3 py-2 text-xs text-[var(--text-weaker)]`,children:`No active agents.`}):(0,R.jsx)(`div`,{className:`flex flex-col gap-2`,children:c.map(t=>(0,R.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[t.parentLive?(0,R.jsx)(AG,{session:t.parent,assistants:o.get(t.parent.id)??[],running:!!n[t.parent.id],queued:!!r[t.parent.id],onOpen:e}):(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1 text-[11px] font-medium text-[var(--text-weaker)]`,children:[(0,R.jsx)(`span`,{className:`truncate`,children:t.parent.title||wG(t.parent.location?.directory)||t.parent.id.slice(0,8)}),(0,R.jsxs)(`span`,{className:`font-mono text-[10px]`,children:[`· `,t.children.length,` subagent`,t.children.length===1?``:`s`]})]}),t.children.length>0&&(0,R.jsx)(`div`,{className:`ml-3 flex flex-col gap-1 border-l border-[var(--border-weak-base)] pl-2`,children:t.children.map(t=>(0,R.jsx)(AG,{session:t,assistants:o.get(t.id)??[],running:!!n[t.id],queued:!!r[t.id],onOpen:e},t.id))})]},t.parent.id))})}function MG(){let e=J(e=>e.running),t=J(e=>e.queued),n=J(e=>e.live),r=J(e=>e.activeIDs),[,i]=(0,E.useState)(0),a=(0,E.useMemo)(()=>{let e=new Map;for(let t of n){let n=e.get(t.sessionID)??[];n.push(t),e.set(t.sessionID,n)}return e},[n]),o=n=>e[n]||t[n]||(a.get(n)??[]).some(e=>e.finish===void 0)?!0:r.includes(n)&&Date.now()-Jg(n)<CG,s=(0,E.useMemo)(()=>{let i=new Set([...Object.keys(e),...Object.keys(t),...r,...n.map(e=>e.sessionID)]);for(let e of i)if(o(e))return!0;return!1},[e,t,r,n,a]);(0,E.useEffect)(()=>{if(s)return og({name:`activity-strip-tick`,minInterval:1e3,run:()=>i(e=>e+1)})},[s]);let[c,l]=(0,E.useState)(()=>{try{return localStorage.getItem(SG)===`1`}catch{return!1}}),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),m=typeof window<`u`&&`documentPictureInPicture`in window;(0,E.useEffect)(()=>{try{localStorage.setItem(SG,c?`1`:`0`)}catch{}},[c]);let h=(0,E.useMemo)(()=>{let i=new Set([...Object.keys(e),...Object.keys(t),...r,...n.map(e=>e.sessionID)]),a=0;for(let e of i)o(e)&&a++;return a},[e,t,r,n,a]);if(!s)return null;let g=e=>void Jv(e),_=async()=>{if(u){u.close(),d(null),p(null);return}try{let e=await window.documentPictureInPicture.requestWindow({width:380,height:560});DG(e),e.document.body.style.margin=`0`,e.document.documentElement.style.background=`var(--background-base)`,e.document.body.style.background=`var(--background-base)`,e.document.body.style.fontFamily=getComputedStyle(document.body).fontFamily;let t=e.document.createElement(`div`);t.id=`activity-strip-pip-root`,t.style.height=`100vh`,t.style.overflow=`auto`,t.style.background=`var(--background-base)`,e.document.body.appendChild(t),p(t),d(e),e.addEventListener(`pagehide`,()=>{d(null),p(null)})}catch(e){console.warn(`PiP failed`,e)}};return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`shrink-0 border-t border-[var(--border-base)] bg-[var(--background-base)]`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between gap-2 px-3 py-1.5`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium text-[var(--text-strong)]`,children:[(0,R.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-emerald-500`,"aria-hidden":!0}),h,` active`,(0,R.jsx)(`span`,{className:`font-normal text-[var(--text-weaker)]`,children:`· streaming`})]}),(0,R.jsxs)(`div`,{className:`flex items-center gap-1`,children:[m&&(0,R.jsxs)(`button`,{type:`button`,onClick:_,title:u?`Close picture-in-picture`:`Pop out — always on top outside Chrome`,className:`inline-flex cursor-pointer items-center gap-1 rounded-md border px-1.5 py-0.5 text-[11px] ${u?`border-[var(--border-selected)] bg-[var(--surface-interactive-weak)] text-[var(--text-interactive-base)]`:`border-[var(--border-weak-base)] text-[var(--text-weaker)] hover:text-[var(--text-strong)]`}`,children:[(0,R.jsx)(ze,{className:`size-3`}),` `,u?`popped`:`pop out`]}),(0,R.jsx)(`button`,{type:`button`,onClick:()=>l(e=>!e),title:c?`Expand`:`Collapse`,className:`flex size-6 cursor-pointer items-center justify-center rounded-md text-[var(--text-weaker)] hover:bg-[var(--surface-base-hover)] hover:text-[var(--text-strong)]`,children:c?(0,R.jsx)(I,{className:`size-3.5`}):(0,R.jsx)(oe,{className:`size-3.5`})})]})]}),c?null:(0,R.jsx)(`div`,{className:`max-h-[42vh] overflow-auto px-2 pb-2`,children:(0,R.jsx)(jG,{onOpen:g})})]}),u&&f?(0,jr.createPortal)((0,R.jsxs)(`div`,{className:`min-h-screen bg-[var(--background-base)] p-2`,children:[(0,R.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,R.jsxs)(`span`,{className:`text-xs font-medium text-[var(--text-strong)]`,children:[`Live — `,h,` active`]}),(0,R.jsx)(`button`,{type:`button`,onClick:_,className:`rounded-md border border-[var(--border-weak-base)] px-1.5 py-0.5 text-[11px] text-[var(--text-weaker)]`,children:`close`})]}),(0,R.jsx)(jG,{onOpen:e=>{Jv(e);try{window.focus()}catch{}}})]}),f):null]})}function NG(e){let t=e.toLowerCase().split(`+`).map(e=>e.trim()).filter(Boolean),n=!1,r=!1,i=!1,a=!1,o=``;for(let e of t)e===`ctrl`||e===`control`?n=!0:e===`meta`||e===`cmd`||e===`command`||e===`super`?r=!0:e===`shift`?i=!0:e===`alt`||e===`option`?a=!0:o=e;return{ctrl:n,meta:r,shift:i,alt:a,key:o}}function PG(e,t){let n=NG(e);return!n.key||n.ctrl!==t.ctrlKey||n.meta!==t.metaKey||n.shift!==t.shiftKey||n.alt!==t.altKey?!1:t.key.toLowerCase()===n.key.toLowerCase()}function FG(e){let t=e;return t?t.isContentEditable||t.closest?.(`input, textarea, select, [contenteditable=true]`)?!0:t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`:!1}function IG(){return(0,E.useEffect)(()=>{let e=St(),t=pt(()=>{e=St()}),n=t=>{if(!t.repeat&&!FG(t.target)&&!document.querySelector(`[role="dialog"], [cmdk-root], [data-radix-popper-content-wrapper], [role="menu"], [role="listbox"]`))for(let n of e){let e=n.keybind;if(e&&PG(e,t)){t.preventDefault();try{let e=Ng().currentSessionID??void 0;n.run({sessionID:e})}catch(e){console.error(`[extensions] command "${n.id}" keybind failed:`,e)}break}}};return window.addEventListener(`keydown`,n),()=>{t(),window.removeEventListener(`keydown`,n)}},[]),null}function LG(){let e=(0,E.useSyncExternalStore)(DS,OS,OS);return e.length===0?null:(0,R.jsx)(`div`,{className:`pointer-events-none fixed right-4 bottom-4 z-50 flex w-[min(22rem,calc(100vw-2rem))] flex-col gap-2`,children:e.map(e=>(0,R.jsxs)(`div`,{role:`status`,className:`pointer-events-auto flex flex-col gap-0.5 rounded-md border px-3 py-2.5 shadow-lg backdrop-blur-sm transition-all ${e.variant===`destructive`?`border-[color:var(--surface-critical-strong)] bg-[color-mix(in_oklch,var(--surface-critical-strong)_12%,var(--surface-float-base))] text-[var(--text-strong)]`:`border-[var(--border-weak-base)] bg-[var(--surface-float-base)] text-[var(--text-strong)]`}`,children:[(0,R.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[(0,R.jsx)(`span`,{className:`text-sm font-medium leading-tight`,children:e.title}),(0,R.jsx)(`button`,{type:`button`,onClick:()=>kS(e.id),className:`shrink-0 cursor-pointer text-[var(--text-weaker)] transition-colors hover:text-[var(--text-strong)]`,"aria-label":`Dismiss`,children:`✕`})]}),e.description?(0,R.jsx)(`span`,{className:`text-xs leading-snug text-[var(--text-weak)]`,children:e.description}):null]},e.id))})}function RG(e,t=`main`){let n=Ng();if(n.currentSessionID&&Sg(n).some(e=>e.req.sessionID===n.currentSessionID))return;wv();let r=document.getElementById(`composer-input-${t}`);if(r){r.focus({preventScroll:!0});return}zG(e,t)}function zG(e,t){let n=0,r=()=>{let i=document.getElementById(`composer-input-${t}`);if(!i){n++===2&&Ev(),n<30&&requestAnimationFrame(r);return}i.focus({preventScroll:!0});let a=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,`value`)?.set;if(a){a.call(i,i.value+e),i.dispatchEvent(new Event(`input`,{bubbles:!0}));let t=i.value.length;i.setSelectionRange(t,t)}};requestAnimationFrame(r)}var BG=/^\/ext\/([A-Za-z0-9_-]+)$/,VG=`webui:navigate`;function HG(){let[e,t]=(0,E.useState)(()=>window.location.pathname);return(0,E.useEffect)(()=>{let e=()=>t(window.location.pathname);return window.addEventListener(`popstate`,e),window.addEventListener(VG,e),()=>{window.removeEventListener(`popstate`,e),window.removeEventListener(VG,e)}},[]),e}function UG(){let e=J(e=>e.currentSessionID),t=J(e=>e.connected),n=J(e=>e.currentSessionID?e.sessions.find(t=>t.id===e.currentSessionID)??e.sessionDetails[e.currentSessionID]:void 0),r=J(e=>e.sessions),i=J(e=>e.runsPanelOpen),a=J(t=>kv(t,e)),o=J(e=>e.panes[0]?.sessionID??null),s=J(e=>e.panes.slice(1)),c=J(e=>e.focusedPane),l=HG(),u=BG.exec(l)?.[1]??null,d=(u?At(u):void 0)?.title;(0,E.useEffect)(()=>{if(d!==void 0){document.title=d;return}document.title=e?`${a?`● `:``}${Eg(e)?`New session`:n?.title??`Untitled session`}`:`OpenCode Web`},[e,n?.title,a,d]);function f(){return!!document.querySelector(`[role="dialog"]`)||i}let p=e=>void Jv(e);function m(t){if(!e||!n?.parentID||f())return;let i=Ov(r,n.parentID).slice().sort((e,t)=>e.id<t.id?-1:1);if(i.length===0)return;let a=i.findIndex(t=>t.id===e),o=(((a===-1?0:a)+t)%i.length+i.length)%i.length;p(i[o].id)}(0,E.useEffect)(()=>{let e=e=>{if(e.key.length!==1||e.metaKey)return;let t=e.ctrlKey&&e.altKey;if(e.ctrlKey&&!t||e.altKey&&!t)return;let n=e.target;n&&(n.isContentEditable||n.closest(`input, textarea, select, [contenteditable=true]`))||document.querySelector(`[role="dialog"], [cmdk-root], [data-radix-popper-content-wrapper], [role="menu"], [role="listbox"]`)||RG(e.key,Yv())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);function h(){if(f())return;let e=document.getElementById(`session-search`);e&&(e.focus(),e.select())}hb({arrowup:()=>{!n?.parentID||!e||f()||p(n.parentID)},arrowdown:()=>{!e||f()||Cv()},arrowleft:()=>m(-1),arrowright:()=>m(1),enter:()=>{!n?.parentID||!e||f()||Ev()},backspace:()=>{if(!n?.parentID||!e||f())return;let t=document.getElementById(`composer-input-${Yv()}`);t&&t.value!==``||p(n.parentID)},"ctrl+n":()=>Wy(null),"ctrl+\\":()=>Uv(),"meta+f":h,"ctrl+f":h,escape:e=>{let t=e?.target;document.querySelector(`[role="dialog"]`)||t&&(t.id.startsWith(`composer-input`)||t.closest(`[data-radix-popper-content-wrapper], [cmdk-root], [data-slot="command"]`))||Iy()}});let g=e=>()=>void Hv(e);return(0,R.jsxs)(`div`,{className:`flex h-dvh flex-col overflow-hidden`,children:[(0,R.jsx)(Nt,{region:`app.header`,sessionID:e??void 0}),(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,R.jsx)(KI,{}),(0,R.jsxs)(`div`,{className:`flex min-w-0 flex-1 overflow-x-auto`,children:[(0,R.jsx)(`section`,{className:`flex min-w-0 flex-1 flex-col`,onPointerDownCapture:g(wg),onFocusCapture:g(wg),children:u?(0,R.jsx)(KG,{id:u}):o?(0,R.jsx)(IF,{sessionID:o,paneKey:`main`,focused:c===wg,onNavigate:p},o):(0,R.jsx)(GG,{connected:t})}),s.map(e=>(0,R.jsx)(`section`,{className:`pane-surface hidden min-w-0 border-l border-[var(--border-base)] lg:flex`,style:{flex:`1 1 0`,maxWidth:`50%`},onPointerDownCapture:g(e.id),onFocusCapture:g(e.id),children:e.sessionID?(0,R.jsx)(IF,{sessionID:e.sessionID,paneKey:e.id,focused:c===e.id,onClose:()=>void Kv(e.id),onNavigate:p},`${e.id}:${e.sessionID}`):(0,R.jsx)(`div`,{className:`flex flex-1 items-center justify-center text-sm text-[var(--text-weaker)]`,children:`Empty pane`})},e.id)),(0,R.jsx)(`div`,{className:`hidden w-9 shrink-0 flex-col items-center border-l border-[var(--border-base)] pt-2 lg:flex`,children:(0,R.jsx)(`button`,{type:`button`,onClick:Uv,disabled:s.length>=3,title:`Split view — open a session beside this one`,className:`flex size-7 cursor-pointer items-center justify-center rounded-md text-[var(--text-weaker)] transition-colors hover:bg-[color:var(--surface-base-hover)] hover:text-[var(--text-strong)] disabled:pointer-events-none disabled:opacity-40`,children:(0,R.jsx)(le,{className:`size-4`})})})]})]}),(0,R.jsx)(MG,{}),(0,R.jsx)(Nt,{region:`footer`}),(0,R.jsx)(WG,{}),(0,R.jsx)(_G,{}),(0,R.jsx)(yb,{}),(0,R.jsx)(IG,{}),(0,R.jsx)(LG,{}),(0,R.jsx)(ZF,{}),(0,R.jsx)(cG,{trigger:(0,R.jsx)(`span`,{className:`hidden`})})]})}function WG(){let e=J(e=>Sg(e).filter(t=>t.req.sessionID!==e.currentSessionID)),t=e.map(e=>e.req.id).join(`,`);return(0,E.useEffect)(()=>{t&&Hh(`chip`,`foreign waiting: ${t}`)},[t]),e.length===0?null:(0,R.jsxs)(`button`,{type:`button`,onClick:()=>void Pv(e[0].req.sessionID,{history:`push`}),title:e.map(e=>`${e.kind} — ${e.req.sessionID}`).join(`
|
|
122
|
-
`),className:`fixed right-4 bottom-10 z-40 flex items-center gap-1.5 rounded-full border border-[color-mix(in_oklch,var(--surface-warning-strong)_45%,transparent)] bg-[var(--surface-float-base)] px-2.5 py-1 text-xs text-[var(--text-weak)] shadow-md transition-colors hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-[color:var(--surface-warning-strong)]`,"aria-hidden":!0}),e.length,` waiting in other session`,e.length>1?`s`:``,` — switch`]})}function GG({connected:e}){return(0,R.jsxs)(`div`,{className:`flex flex-1 flex-col items-center justify-center gap-3 text-neutral-500`,children:[(0,R.jsx)(`div`,{className:`size-2.5 rounded-full ${e?`bg-emerald-500`:`bg-amber-500`}`}),(0,R.jsx)(`p`,{className:`text-sm`,children:e?`Select or create a session on the left`:`Connecting to the opencode service…`})]})}function KG({id:e}){qG();let t=At(e),n=Tt();return(0,R.jsx)(`div`,{className:`pane-surface flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto`,children:(0,R.jsxs)(`div`,{className:`mx-auto w-full max-w-3xl px-6 py-6`,children:[(0,R.jsx)(`div`,{className:`flex items-start justify-between gap-4`,children:(0,R.jsxs)(`div`,{className:`min-w-0`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsxs)(`button`,{type:`button`,onClick:()=>window.history.back(),title:`Go back`,className:`inline-flex cursor-pointer items-center gap-1 rounded-md border border-[var(--border-weak-base)] px-1.5 py-0.5 text-xs text-[var(--text-weak)] transition-colors hover:border-[var(--border-selected)] hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(ee,{className:`size-3`}),`Back`]}),(0,R.jsx)(`h1`,{className:`truncate text-[var(--font-size-large)] font-medium text-[var(--text-strong)]`,children:t?t.title:`Unknown extension page`})]}),t?.description&&(0,R.jsx)(`p`,{className:`mt-1 text-sm text-[var(--text-weaker)]`,children:t.description})]})}),(0,R.jsx)(`div`,{className:`mt-4`,children:t?t.render({}):(0,R.jsxs)(`div`,{className:`flex flex-col gap-2 text-sm text-[var(--text-weak)]`,children:[(0,R.jsxs)(`p`,{children:[`No extension registered “`,e,`”. Available pages:`]}),n.length===0?(0,R.jsx)(`p`,{className:`text-[var(--text-weaker)]`,children:`No extension pages are registered.`}):(0,R.jsx)(`ul`,{className:`flex flex-col gap-1`,children:n.map(e=>(0,R.jsx)(`li`,{children:(0,R.jsxs)(`a`,{href:`/ext/${e.id}`,title:e.description??e.title,className:`text-[var(--text-interactive-base)] underline underline-offset-2`,children:[`/ext/`,e.id,` — `,e.title]})},e.id))})]})})]})})}function qG(){let[e,t]=(0,E.useState)(0);return(0,E.useEffect)(()=>pt(()=>t(e=>e+1)),[]),[e]}var JG=class extends E.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e){console.error(`[app] render error:`,e)}render(){return this.state.error?(0,R.jsxs)(`div`,{className:`flex size-full flex-col items-center justify-center gap-3 bg-background p-6 text-center`,children:[(0,R.jsx)(`p`,{className:`text-sm text-foreground`,children:`The UI hit a render error.`}),(0,R.jsx)(`pre`,{className:`max-h-48 max-w-full overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs whitespace-pre-wrap text-muted-foreground`,children:this.state.error.message}),(0,R.jsx)(`button`,{type:`button`,onClick:()=>this.setState({error:null}),className:`cursor-pointer rounded-md border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-muted`,children:`Retry`})]}):this.props.children}},YG=Object.assign({"./report/index.tsx":()=>ug(()=>import(`./report-
|
|
122
|
+
`),className:`fixed right-4 bottom-10 z-40 flex items-center gap-1.5 rounded-full border border-[color-mix(in_oklch,var(--surface-warning-strong)_45%,transparent)] bg-[var(--surface-float-base)] px-2.5 py-1 text-xs text-[var(--text-weak)] shadow-md transition-colors hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-[color:var(--surface-warning-strong)]`,"aria-hidden":!0}),e.length,` waiting in other session`,e.length>1?`s`:``,` — switch`]})}function GG({connected:e}){return(0,R.jsxs)(`div`,{className:`flex flex-1 flex-col items-center justify-center gap-3 text-neutral-500`,children:[(0,R.jsx)(`div`,{className:`size-2.5 rounded-full ${e?`bg-emerald-500`:`bg-amber-500`}`}),(0,R.jsx)(`p`,{className:`text-sm`,children:e?`Select or create a session on the left`:`Connecting to the opencode service…`})]})}function KG({id:e}){qG();let t=At(e),n=Tt();return(0,R.jsx)(`div`,{className:`pane-surface flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto`,children:(0,R.jsxs)(`div`,{className:`mx-auto w-full max-w-3xl px-6 py-6`,children:[(0,R.jsx)(`div`,{className:`flex items-start justify-between gap-4`,children:(0,R.jsxs)(`div`,{className:`min-w-0`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsxs)(`button`,{type:`button`,onClick:()=>window.history.back(),title:`Go back`,className:`inline-flex cursor-pointer items-center gap-1 rounded-md border border-[var(--border-weak-base)] px-1.5 py-0.5 text-xs text-[var(--text-weak)] transition-colors hover:border-[var(--border-selected)] hover:text-[var(--text-strong)]`,children:[(0,R.jsx)(ee,{className:`size-3`}),`Back`]}),(0,R.jsx)(`h1`,{className:`truncate text-[var(--font-size-large)] font-medium text-[var(--text-strong)]`,children:t?t.title:`Unknown extension page`})]}),t?.description&&(0,R.jsx)(`p`,{className:`mt-1 text-sm text-[var(--text-weaker)]`,children:t.description})]})}),(0,R.jsx)(`div`,{className:`mt-4`,children:t?t.render({}):(0,R.jsxs)(`div`,{className:`flex flex-col gap-2 text-sm text-[var(--text-weak)]`,children:[(0,R.jsxs)(`p`,{children:[`No extension registered “`,e,`”. Available pages:`]}),n.length===0?(0,R.jsx)(`p`,{className:`text-[var(--text-weaker)]`,children:`No extension pages are registered.`}):(0,R.jsx)(`ul`,{className:`flex flex-col gap-1`,children:n.map(e=>(0,R.jsx)(`li`,{children:(0,R.jsxs)(`a`,{href:`/ext/${e.id}`,title:e.description??e.title,className:`text-[var(--text-interactive-base)] underline underline-offset-2`,children:[`/ext/`,e.id,` — `,e.title]})},e.id))})]})})]})})}function qG(){let[e,t]=(0,E.useState)(0);return(0,E.useEffect)(()=>pt(()=>t(e=>e+1)),[]),[e]}var JG=class extends E.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e){console.error(`[app] render error:`,e)}render(){return this.state.error?(0,R.jsxs)(`div`,{className:`flex size-full flex-col items-center justify-center gap-3 bg-background p-6 text-center`,children:[(0,R.jsx)(`p`,{className:`text-sm text-foreground`,children:`The UI hit a render error.`}),(0,R.jsx)(`pre`,{className:`max-h-48 max-w-full overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs whitespace-pre-wrap text-muted-foreground`,children:this.state.error.message}),(0,R.jsx)(`button`,{type:`button`,onClick:()=>this.setState({error:null}),className:`cursor-pointer rounded-md border border-border px-3 py-1.5 text-xs text-foreground transition-colors hover:bg-muted`,children:`Retry`})]}):this.props.children}},YG=Object.assign({"./report/index.tsx":()=>ug(()=>import(`./report-BVQPFnRg.js`),[]),"./runtime-status/index.tsx":()=>ug(()=>import(`./runtime-status-CHh7J96X.js`),[])});async function XG(){let e=new Set;await Promise.all(Object.values(YG).map(async t=>{let n=await t();n&&typeof n.id==`string`&&e.add(n.id)})),ht(e)}XG();var ZG=new Map,QG=8e3;function $G(){let e=window,t=e.__opencodeUI??{};t.notify||=AS,t.getHooks||=kt,t.register||=yt,t.version||fetch(`/api/webui/config`).then(e=>e.ok?e.json():null).then(e=>{if(!e)return;let t=window.__opencodeUI;e.version&&(t.version=e.version),e.reportRepo&&(t.reportRepo=e.reportRepo)}).catch(()=>{}),e.__opencodeUI=t}var eK=!1;async function tK(e){if($G(),!e?.force&&eK&&document.hidden)return;let t;try{let e=await fetch(`/api/webui/extensions`);if(!e.ok)return;let n=(await e.json())?.data;t=Array.isArray(n)?n:[]}catch{return}let n=new Set;for(let e of t)if(typeof e?.id==`string`&&typeof e?.url==`string`&&!aS(e.id)&&(n.add(e.id),gt([e.id]),ZG.get(e.id)!==e.url))try{await ug(()=>import(e.url),[]),ZG.set(e.id,e.url)}catch{}let r=[];for(let e of ZG.keys())n.has(e)||(r.push(e),ZG.delete(e));r.length>0&&_t(r)}function nK(){eK||(eK=!0,$G(),tK({force:!0}),og({name:`extensions-manifest`,minInterval:QG,run:()=>tK()}))}var rK=typeof localStorage<`u`&&localStorage.getItem(`webui.debug`)===`1`;window.__WEBUI_DEBUG_CONSOLE__=rK,window.__opencodeUI={version:1,register:yt,react:E,jsxRuntime:R,useStore:J,api:G,notify:AS,getHooks:kt},nK(),mv(),Hh(`boot`,`app render (console mirror: ${rK?`on`:`off`})`),(0,ot.createRoot)(document.getElementById(`root`)).render((0,R.jsx)(E.StrictMode,{children:(0,R.jsx)(JG,{children:(0,R.jsx)(UG,{})})}));export{ey as a,st as c,Yy as i,p as l,Ng as n,J as o,Eg as r,yt as s,AS as t,l as u};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,c as t,i as n,n as r,r as i,s as a,t as o}from"./index-
|
|
1
|
+
import{a as e,c as t,i as n,n as r,r as i,s as a,t as o}from"./index-Ca0YxAh-.js";var s=`report`,c=`AbdelftahZowail/opencode-webui`,l=10,u=window;function d(e){let t=u.__reportErrors??=[];t.push(e),t.length>l&&t.splice(0,t.length-l)}u.__reportErrorsInstalled||(u.__reportErrorsInstalled=!0,window.onerror=(e,t,n,r,i)=>{d({message:String(e).slice(0,500),source:t??``,line:n??0,stack:i instanceof Error?i.stack?.slice(0,500):void 0})},window.addEventListener(`unhandledrejection`,e=>{let t=e.reason;d({message:(t instanceof Error?t.message:String(t)).slice(0,500),source:`unhandledrejection`,line:0,stack:t instanceof Error?t.stack?.slice(0,500):void 0})}));async function f(e){try{let t=await fetch(e);return t.ok?await t.json():null}catch{return null}}async function p(e){let[n,r]=await Promise.all([f(`/api/webui/config`),f(`/api/webui/extensions`)]);return{url:location.href,userAgent:navigator.userAgent,language:navigator.language,viewport:`${window.innerWidth}x${window.innerHeight}`,version:n?.version??`unknown`,reportRepo:n?.reportRepo??c,builtins:[...t],runtimeExtensions:(r?.data??[]).map(e=>e.id??``).filter(Boolean),errors:u.__reportErrors??[],sessionID:e,timestamp:new Date().toISOString()}}function m(e,t){let n=`WebUI bug: ${e?e.slice(0,80):`user report`}`,r=[`### What happened`,e||``,``,`### Steps to reproduce`,`1. `,``,`### Expected`,``,`### Actual`,``,`<details><summary>Diagnostics</summary>`,``,"```json",JSON.stringify(t,null,2),"```",`</details>`].join(`
|
|
2
2
|
`);return{title:n,body:r,url:`https://github.com/${t.reportRepo}/issues/new?title=${encodeURIComponent(n)}&body=${encodeURIComponent(r)}`}}async function h(e){try{return await navigator.clipboard.writeText(e),!0}catch{return!1}}async function g(t,a){let s=t.trim(),c=s.startsWith(`--agent`),l=c?s.replace(/^--agent\b/,``).trim():s,u=await p(a.sessionID??r().currentSessionID??null),{title:d,body:f,url:g}=m(l,u);if(c){let t=`File a bug against ${u.reportRepo} using the gh CLI: create an issue with the title and body below, then reply with the issue URL. Do not include any private session content beyond the diagnostics JSON.\n\nTitle: ${d}\n\n${f}`,s=a.sessionID??r().currentSessionID??null;if(s&&i(s))try{s=await n(``)}catch{s=null}if(!s){let e=await h(t);o({title:e?`No active session — report prompt copied`:`No active session`,description:e?`Paste it into a session to have the agent file the issue.`:`Could not copy the report prompt either.`,variant:e?`default`:`destructive`});return}o({title:`Report handed to the agent`,description:`It will file the issue and reply with the URL.`}),await e(s,t);return}if(window.open(g,`_blank`))o({title:`Opening GitHub issue…`});else{let e=await h(g);o({title:e?`Report ready — link copied`:`Report link`,description:e?`Popup blocked; paste the link in a browser.`:`Popup blocked and the clipboard is unavailable.`,variant:e?`default`:`destructive`})}}a({kind:`slash`,id:`report`,name:`report`,aliases:[`bug`],description:`Report a webui bug on GitHub — diag bundle prefilled`,run:g});export{s as id};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{l as e,o as t,s as n,u as r}from"./index-
|
|
1
|
+
import{l as e,o as t,s as n,u as r}from"./index-Ca0YxAh-.js";var i=r(e(),1),a=`runtime-status`;function o(){let e=t(e=>e.connected),n=t(e=>e.serviceOK),r=t(e=>e.activeIDs.length),a=e&&n;return(0,i.jsxs)(`footer`,{className:`flex min-h-7 items-center justify-end gap-3 border-t border-[var(--border-weak-base)] bg-[var(--background-base)] px-3 py-1 font-mono text-[10px] text-[var(--text-weaker)]`,children:[(0,i.jsx)(`span`,{className:`hidden sm:inline`,children:`webui extension`}),(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,title:a?`Connected to the OpenCode service`:`Waiting for the OpenCode service`,children:[(0,i.jsx)(`span`,{className:`size-1.5 rounded-full ${a?`bg-[var(--surface-success-strong)]`:`bg-[var(--surface-warning-strong)]`}`}),a?`connected`:`offline`]}),r>0&&(0,i.jsxs)(`span`,{children:[r,` active`]})]})}n({kind:`region`,id:`runtime-status`,region:`footer`,render:()=>(0,i.jsx)(o,{})});export{a as id};
|
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/assets/opencode.svg" />
|
|
7
7
|
<title>OpenCode Web</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Ca0YxAh-.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-BJLgA6bC.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Web UI for the OpenCode coding agent — chat, streaming, tool cards, and extensions over the OpenCode engine's HTTP API.",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.4",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
package/skills/webui/SKILL.md
CHANGED
|
@@ -10,6 +10,27 @@ the `opencode` TUI, with a Bun proxy in front so the browser never holds
|
|
|
10
10
|
service credentials. One port for UI + `/api/*`: http://localhost:4097
|
|
11
11
|
(`WEBUI_PROXY_PORT`).
|
|
12
12
|
|
|
13
|
+
- **Repo**: https://github.com/AbdelftahZowail/opencode-webui
|
|
14
|
+
- **This skill's version**: 1.0.4 (matches the `v1.0.4` git tag —
|
|
15
|
+
the file links below are pinned to it, so they always describe the code
|
|
16
|
+
this skill was generated with)
|
|
17
|
+
- **A running instance exposes its version** at `GET /api/webui/config` →
|
|
18
|
+
`{ version, reportRepo }`, and on the page as `window.__opencodeUI.version`.
|
|
19
|
+
|
|
20
|
+
## Source catalog (fetch, don't read local checkouts)
|
|
21
|
+
|
|
22
|
+
Everything needed to author extensions is below; when a table isn't enough,
|
|
23
|
+
fetch the exact file at the pinned tag instead of reading a local clone:
|
|
24
|
+
|
|
25
|
+
| File | Purpose |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/ui-extensions/README.md | Full authoring guide — the source of truth for kinds/hooks/regions |
|
|
28
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/src/extensions/registry.tsx | The slot registry — exact register() shapes per kind |
|
|
29
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/src/components/Composer.tsx | Where slash entries / prompt hooks / composer regions live |
|
|
30
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/src/components/MessageItem.tsx | Where message/message.decoration/message.part render |
|
|
31
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/src/lib/composerHandoff.ts | Type-anywhere → composer behavior (if your extension competes for keys) |
|
|
32
|
+
| https://raw.githubusercontent.com/AbdelftahZowail/opencode-webui/v1.0.4/src/store.ts | The store — actions useStore exposes to extensions |
|
|
33
|
+
|
|
13
34
|
## Environment
|
|
14
35
|
|
|
15
36
|
| Variable | Default | Purpose |
|
|
@@ -32,14 +53,26 @@ service credentials. One port for UI + `/api/*`: http://localhost:4097
|
|
|
32
53
|
- **Author a user-dir extension** for the user — a folder, no build step, no
|
|
33
54
|
restart.
|
|
34
55
|
|
|
56
|
+
### Dev extensions vs user extensions (two homes, one contract)
|
|
57
|
+
|
|
58
|
+
| | Dev (app repo) | User (any machine) |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| Where | `ui-extensions/<name>/` in the webui checkout | `~/.config/opencode/webui-extensions/<name>/main.tsx` (per-user) or `<project>/.opencode/webui-extensions/<name>/main.tsx` (per-project) |
|
|
61
|
+
| How it loads | Bundled into the app build, listed in `ui-extensions/index.ts` | The proxy bundles it on the fly; page picks it up within ~8s |
|
|
62
|
+
| On/off | `enabled` list in `ui-extensions/config.ts` | Settings › Extensions toggle |
|
|
63
|
+
| API surface | Full app internals (imports, `useStore`, `api`) | ONLY the `window.__opencodeUI` bridge (`register`, `react`, `useStore`, `api`, `notify`, `getHooks`, `version`) |
|
|
64
|
+
|
|
65
|
+
Authoring rules (kinds, hook events) are identical in both homes — the tables
|
|
66
|
+
below apply to each.
|
|
67
|
+
|
|
35
68
|
### Minimal user-dir extension
|
|
36
69
|
|
|
37
70
|
Drop a folder — `~/.config/opencode/webui-extensions/<name>/main.tsx`
|
|
38
71
|
(per-user) or `<project>/.opencode/webui-extensions/<name>/main.tsx`
|
|
39
72
|
(per-project). The proxy bundles it and the page loads it within a poll cycle
|
|
40
|
-
|
|
41
|
-
the app ONLY through the
|
|
42
|
-
`react`, `useStore`, `api`, `notify`, `getHooks`):
|
|
73
|
+
`~8s` — see the dev-vs-user split above). Runtime extensions reach
|
|
74
|
+
the app ONLY through the `window.__opencodeUI` bridge (`register`,
|
|
75
|
+
`react`, `useStore`, `api`, `notify`, `getHooks`, `version`):
|
|
43
76
|
|
|
44
77
|
```tsx
|
|
45
78
|
// ~/.config/opencode/webui-extensions/hello/main.tsx
|