remote-codex 0.1.10 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/apps/supervisor-api/dist/chunk-6M32PPHZ.js +24507 -0
  2. package/apps/supervisor-api/dist/chunk-7AA2MFXK.js +24499 -0
  3. package/apps/supervisor-api/dist/chunk-HKBFCPHH.js +24511 -0
  4. package/apps/supervisor-api/dist/index.js +12525 -28436
  5. package/apps/supervisor-api/dist/worker-index.d.ts +2 -0
  6. package/apps/supervisor-api/dist/worker-index.js +33 -0
  7. package/apps/supervisor-web/dist/assets/{highlighted-body-OFNGDK62-CyMcatlD.js → highlighted-body-OFNGDK62-p31aS0f0.js} +1 -1
  8. package/apps/supervisor-web/dist/assets/index-BiuFei_K.css +32 -0
  9. package/apps/supervisor-web/dist/assets/index-D1R9CUnx.js +2161 -0
  10. package/apps/supervisor-web/dist/assets/{xterm-DbYWMNQ0.js → xterm-D92BViLH.js} +1 -1
  11. package/apps/supervisor-web/dist/index.html +2 -2
  12. package/package.json +2 -3
  13. package/packages/agent-runtime/src/index.ts +4 -0
  14. package/packages/agent-runtime/src/management-errors.ts +11 -0
  15. package/packages/agent-runtime/src/model-pricing.ts +325 -0
  16. package/packages/agent-runtime/src/registry.ts +19 -4
  17. package/packages/agent-runtime/src/runtime-errors.ts +97 -0
  18. package/packages/agent-runtime/src/types.ts +36 -3
  19. package/packages/agent-runtime/src/unavailable-runtime.ts +169 -0
  20. package/packages/claude/src/historyItems.ts +41 -5
  21. package/packages/claude/src/runtimeAdapter.test.ts +117 -6
  22. package/packages/claude/src/runtimeAdapter.ts +421 -65
  23. package/packages/codex/src/historyItems.test.ts +137 -0
  24. package/packages/codex/src/historyItems.ts +135 -17
  25. package/packages/codex/src/hookHistory.test.ts +59 -0
  26. package/packages/codex/src/index.ts +7 -0
  27. package/packages/codex/src/local-session-store.ts +390 -0
  28. package/packages/codex/src/management/codex-management-service.ts +454 -0
  29. package/packages/codex/src/management/codexHostConfig.test.ts +88 -0
  30. package/packages/codex/src/management/codexHostConfig.ts +188 -0
  31. package/packages/codex/src/management/errors.ts +20 -0
  32. package/packages/codex/src/modelPricing.test.ts +235 -0
  33. package/packages/codex/src/modelPricing.ts +9 -0
  34. package/packages/codex/src/runtime-errors.test.ts +72 -0
  35. package/packages/codex/src/runtime-errors.ts +37 -0
  36. package/packages/codex/src/runtimeAdapter.ts +15 -0
  37. package/packages/codex/src/thread-title.ts +1 -0
  38. package/packages/opencode/src/historyItems.test.ts +504 -0
  39. package/packages/opencode/src/historyItems.ts +896 -0
  40. package/packages/opencode/src/index.ts +2 -0
  41. package/packages/opencode/src/runtimeAdapter.test.ts +1444 -0
  42. package/packages/opencode/src/runtimeAdapter.ts +1473 -0
  43. package/packages/shared/src/agent-providers.ts +56 -0
  44. package/packages/shared/src/index.ts +240 -35
  45. package/apps/supervisor-web/dist/assets/index-BlAhoIuq.js +0 -379
  46. package/apps/supervisor-web/dist/assets/index-DI0NRNgr.css +0 -32
@@ -1,4 +1,4 @@
1
- import{g as Ce}from"./index-BlAhoIuq.js";function be(se,le){for(var ee=0;ee<le.length;ee++){const J=le[ee];if(typeof J!="string"&&!Array.isArray(J)){for(const V in J)if(V!=="default"&&!(V in se)){const te=Object.getOwnPropertyDescriptor(J,V);te&&Object.defineProperty(se,V,te.get?te:{enumerable:!0,get:()=>J[V]})}}}return Object.freeze(Object.defineProperty(se,Symbol.toStringTag,{value:"Module"}))}var ve={exports:{}},ge;function ye(){return ge||(ge=1,(function(se,le){(function(ee,J){se.exports=J()})(self,(()=>(()=>{var ee={4567:function(I,r,a){var c=this&&this.__decorate||function(i,o,l,v){var m,h=arguments.length,g=h<3?o:v===null?v=Object.getOwnPropertyDescriptor(o,l):v;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")g=Reflect.decorate(i,o,l,v);else for(var b=i.length-1;b>=0;b--)(m=i[b])&&(g=(h<3?m(g):h>3?m(o,l,g):m(o,l))||g);return h>3&&g&&Object.defineProperty(o,l,g),g},_=this&&this.__param||function(i,o){return function(l,v){o(l,v,i)}};Object.defineProperty(r,"__esModule",{value:!0}),r.AccessibilityManager=void 0;const n=a(9042),d=a(6114),f=a(9924),p=a(844),u=a(5596),e=a(4725),s=a(3656);let t=r.AccessibilityManager=class extends p.Disposable{constructor(i,o){super(),this._terminal=i,this._renderService=o,this._liveRegionLineCount=0,this._charsToConsume=[],this._charsToAnnounce="",this._accessibilityContainer=document.createElement("div"),this._accessibilityContainer.classList.add("xterm-accessibility"),this._rowContainer=document.createElement("div"),this._rowContainer.setAttribute("role","list"),this._rowContainer.classList.add("xterm-accessibility-tree"),this._rowElements=[];for(let l=0;l<this._terminal.rows;l++)this._rowElements[l]=this._createAccessibilityTreeNode(),this._rowContainer.appendChild(this._rowElements[l]);if(this._topBoundaryFocusListener=l=>this._handleBoundaryFocus(l,0),this._bottomBoundaryFocusListener=l=>this._handleBoundaryFocus(l,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions(),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=document.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this.register(new f.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this.register(this._terminal.onResize((l=>this._handleResize(l.rows)))),this.register(this._terminal.onRender((l=>this._refreshRows(l.start,l.end)))),this.register(this._terminal.onScroll((()=>this._refreshRows()))),this.register(this._terminal.onA11yChar((l=>this._handleChar(l)))),this.register(this._terminal.onLineFeed((()=>this._handleChar(`
1
+ import{g as Ce}from"./index-D1R9CUnx.js";function be(se,le){for(var ee=0;ee<le.length;ee++){const J=le[ee];if(typeof J!="string"&&!Array.isArray(J)){for(const V in J)if(V!=="default"&&!(V in se)){const te=Object.getOwnPropertyDescriptor(J,V);te&&Object.defineProperty(se,V,te.get?te:{enumerable:!0,get:()=>J[V]})}}}return Object.freeze(Object.defineProperty(se,Symbol.toStringTag,{value:"Module"}))}var ve={exports:{}},ge;function ye(){return ge||(ge=1,(function(se,le){(function(ee,J){se.exports=J()})(self,(()=>(()=>{var ee={4567:function(I,r,a){var c=this&&this.__decorate||function(i,o,l,v){var m,h=arguments.length,g=h<3?o:v===null?v=Object.getOwnPropertyDescriptor(o,l):v;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")g=Reflect.decorate(i,o,l,v);else for(var b=i.length-1;b>=0;b--)(m=i[b])&&(g=(h<3?m(g):h>3?m(o,l,g):m(o,l))||g);return h>3&&g&&Object.defineProperty(o,l,g),g},_=this&&this.__param||function(i,o){return function(l,v){o(l,v,i)}};Object.defineProperty(r,"__esModule",{value:!0}),r.AccessibilityManager=void 0;const n=a(9042),d=a(6114),f=a(9924),p=a(844),u=a(5596),e=a(4725),s=a(3656);let t=r.AccessibilityManager=class extends p.Disposable{constructor(i,o){super(),this._terminal=i,this._renderService=o,this._liveRegionLineCount=0,this._charsToConsume=[],this._charsToAnnounce="",this._accessibilityContainer=document.createElement("div"),this._accessibilityContainer.classList.add("xterm-accessibility"),this._rowContainer=document.createElement("div"),this._rowContainer.setAttribute("role","list"),this._rowContainer.classList.add("xterm-accessibility-tree"),this._rowElements=[];for(let l=0;l<this._terminal.rows;l++)this._rowElements[l]=this._createAccessibilityTreeNode(),this._rowContainer.appendChild(this._rowElements[l]);if(this._topBoundaryFocusListener=l=>this._handleBoundaryFocus(l,0),this._bottomBoundaryFocusListener=l=>this._handleBoundaryFocus(l,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions(),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=document.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this.register(new f.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this.register(this._terminal.onResize((l=>this._handleResize(l.rows)))),this.register(this._terminal.onRender((l=>this._refreshRows(l.start,l.end)))),this.register(this._terminal.onScroll((()=>this._refreshRows()))),this.register(this._terminal.onA11yChar((l=>this._handleChar(l)))),this.register(this._terminal.onLineFeed((()=>this._handleChar(`
2
2
  `)))),this.register(this._terminal.onA11yTab((l=>this._handleTab(l)))),this.register(this._terminal.onKey((l=>this._handleKey(l.key)))),this.register(this._terminal.onBlur((()=>this._clearLiveRegion()))),this.register(this._renderService.onDimensionsChange((()=>this._refreshRowsDimensions()))),this._screenDprMonitor=new u.ScreenDprMonitor(window),this.register(this._screenDprMonitor),this._screenDprMonitor.setListener((()=>this._refreshRowsDimensions())),this.register((0,s.addDisposableDomListener)(window,"resize",(()=>this._refreshRowsDimensions()))),this._refreshRows(),this.register((0,p.toDisposable)((()=>{this._accessibilityContainer.remove(),this._rowElements.length=0})))}_handleTab(i){for(let o=0;o<i;o++)this._handleChar(" ")}_handleChar(i){this._liveRegionLineCount<21&&(this._charsToConsume.length>0?this._charsToConsume.shift()!==i&&(this._charsToAnnounce+=i):this._charsToAnnounce+=i,i===`
3
3
  `&&(this._liveRegionLineCount++,this._liveRegionLineCount===21&&(this._liveRegion.textContent+=n.tooMuchOutput)),d.isMac&&this._liveRegion.textContent&&this._liveRegion.textContent.length>0&&!this._liveRegion.parentNode&&setTimeout((()=>{this._accessibilityContainer.appendChild(this._liveRegion)}),0))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0,d.isMac&&this._liveRegion.remove()}_handleKey(i){this._clearLiveRegion(),new RegExp("\\p{Control}","u").test(i)||this._charsToConsume.push(i)}_refreshRows(i,o){this._liveRegionDebouncer.refresh(i,o,this._terminal.rows)}_renderRows(i,o){const l=this._terminal.buffer,v=l.lines.length.toString();for(let m=i;m<=o;m++){const h=l.translateBufferLineToString(l.ydisp+m,!0),g=(l.ydisp+m+1).toString(),b=this._rowElements[m];b&&(h.length===0?b.innerText=" ":b.textContent=h,b.setAttribute("aria-posinset",g),b.setAttribute("aria-setsize",v))}this._announceCharacters()}_announceCharacters(){this._charsToAnnounce.length!==0&&(this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(i,o){const l=i.target,v=this._rowElements[o===0?1:this._rowElements.length-2];if(l.getAttribute("aria-posinset")===(o===0?"1":`${this._terminal.buffer.lines.length}`)||i.relatedTarget!==v)return;let m,h;if(o===0?(m=l,h=this._rowElements.pop(),this._rowContainer.removeChild(h)):(m=this._rowElements.shift(),h=l,this._rowContainer.removeChild(m)),m.removeEventListener("focus",this._topBoundaryFocusListener),h.removeEventListener("focus",this._bottomBoundaryFocusListener),o===0){const g=this._createAccessibilityTreeNode();this._rowElements.unshift(g),this._rowContainer.insertAdjacentElement("afterbegin",g)}else{const g=this._createAccessibilityTreeNode();this._rowElements.push(g),this._rowContainer.appendChild(g)}this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._terminal.scrollLines(o===0?-1:1),this._rowElements[o===0?1:this._rowElements.length-2].focus(),i.preventDefault(),i.stopImmediatePropagation()}_handleResize(i){this._rowElements[this._rowElements.length-1].removeEventListener("focus",this._bottomBoundaryFocusListener);for(let o=this._rowContainer.children.length;o<this._terminal.rows;o++)this._rowElements[o]=this._createAccessibilityTreeNode(),this._rowContainer.appendChild(this._rowElements[o]);for(;this._rowElements.length>i;)this._rowContainer.removeChild(this._rowElements.pop());this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions()}_createAccessibilityTreeNode(){const i=document.createElement("div");return i.setAttribute("role","listitem"),i.tabIndex=-1,this._refreshRowDimensions(i),i}_refreshRowsDimensions(){if(this._renderService.dimensions.css.cell.height){this._accessibilityContainer.style.width=`${this._renderService.dimensions.css.canvas.width}px`,this._rowElements.length!==this._terminal.rows&&this._handleResize(this._terminal.rows);for(let i=0;i<this._terminal.rows;i++)this._refreshRowDimensions(this._rowElements[i])}}_refreshRowDimensions(i){i.style.height=`${this._renderService.dimensions.css.cell.height}px`}};r.AccessibilityManager=t=c([_(1,e.IRenderService)],t)},3614:(I,r)=>{function a(d){return d.replace(/\r?\n/g,"\r")}function c(d,f){return f?"\x1B[200~"+d+"\x1B[201~":d}function _(d,f,p,u){d=c(d=a(d),p.decPrivateModes.bracketedPasteMode&&u.rawOptions.ignoreBracketedPasteMode!==!0),p.triggerDataEvent(d,!0),f.value=""}function n(d,f,p){const u=p.getBoundingClientRect(),e=d.clientX-u.left-10,s=d.clientY-u.top-10;f.style.width="20px",f.style.height="20px",f.style.left=`${e}px`,f.style.top=`${s}px`,f.style.zIndex="1000",f.focus()}Object.defineProperty(r,"__esModule",{value:!0}),r.rightClickHandler=r.moveTextAreaUnderMouseCursor=r.paste=r.handlePasteEvent=r.copyHandler=r.bracketTextForPaste=r.prepareTextForTerminal=void 0,r.prepareTextForTerminal=a,r.bracketTextForPaste=c,r.copyHandler=function(d,f){d.clipboardData&&d.clipboardData.setData("text/plain",f.selectionText),d.preventDefault()},r.handlePasteEvent=function(d,f,p,u){d.stopPropagation(),d.clipboardData&&_(d.clipboardData.getData("text/plain"),f,p,u)},r.paste=_,r.moveTextAreaUnderMouseCursor=n,r.rightClickHandler=function(d,f,p,u,e){n(d,f,p),e&&u.rightClickSelect(d),f.value=u.selectionText,f.select()}},7239:(I,r,a)=>{Object.defineProperty(r,"__esModule",{value:!0}),r.ColorContrastCache=void 0;const c=a(1505);r.ColorContrastCache=class{constructor(){this._color=new c.TwoKeyMap,this._css=new c.TwoKeyMap}setCss(_,n,d){this._css.set(_,n,d)}getCss(_,n){return this._css.get(_,n)}setColor(_,n,d){this._color.set(_,n,d)}getColor(_,n){return this._color.get(_,n)}clear(){this._color.clear(),this._css.clear()}}},3656:(I,r)=>{Object.defineProperty(r,"__esModule",{value:!0}),r.addDisposableDomListener=void 0,r.addDisposableDomListener=function(a,c,_,n){a.addEventListener(c,_,n);let d=!1;return{dispose:()=>{d||(d=!0,a.removeEventListener(c,_,n))}}}},6465:function(I,r,a){var c=this&&this.__decorate||function(e,s,t,i){var o,l=arguments.length,v=l<3?s:i===null?i=Object.getOwnPropertyDescriptor(s,t):i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")v=Reflect.decorate(e,s,t,i);else for(var m=e.length-1;m>=0;m--)(o=e[m])&&(v=(l<3?o(v):l>3?o(s,t,v):o(s,t))||v);return l>3&&v&&Object.defineProperty(s,t,v),v},_=this&&this.__param||function(e,s){return function(t,i){s(t,i,e)}};Object.defineProperty(r,"__esModule",{value:!0}),r.Linkifier2=void 0;const n=a(3656),d=a(8460),f=a(844),p=a(2585);let u=r.Linkifier2=class extends f.Disposable{get currentLink(){return this._currentLink}constructor(e){super(),this._bufferService=e,this._linkProviders=[],this._linkCacheDisposables=[],this._isMouseOut=!0,this._wasResized=!1,this._activeLine=-1,this._onShowLinkUnderline=this.register(new d.EventEmitter),this.onShowLinkUnderline=this._onShowLinkUnderline.event,this._onHideLinkUnderline=this.register(new d.EventEmitter),this.onHideLinkUnderline=this._onHideLinkUnderline.event,this.register((0,f.getDisposeArrayDisposable)(this._linkCacheDisposables)),this.register((0,f.toDisposable)((()=>{this._lastMouseEvent=void 0}))),this.register(this._bufferService.onResize((()=>{this._clearCurrentLink(),this._wasResized=!0})))}registerLinkProvider(e){return this._linkProviders.push(e),{dispose:()=>{const s=this._linkProviders.indexOf(e);s!==-1&&this._linkProviders.splice(s,1)}}}attachToDom(e,s,t){this._element=e,this._mouseService=s,this._renderService=t,this.register((0,n.addDisposableDomListener)(this._element,"mouseleave",(()=>{this._isMouseOut=!0,this._clearCurrentLink()}))),this.register((0,n.addDisposableDomListener)(this._element,"mousemove",this._handleMouseMove.bind(this))),this.register((0,n.addDisposableDomListener)(this._element,"mousedown",this._handleMouseDown.bind(this))),this.register((0,n.addDisposableDomListener)(this._element,"mouseup",this._handleMouseUp.bind(this)))}_handleMouseMove(e){if(this._lastMouseEvent=e,!this._element||!this._mouseService)return;const s=this._positionFromMouseEvent(e,this._element,this._mouseService);if(!s)return;this._isMouseOut=!1;const t=e.composedPath();for(let i=0;i<t.length;i++){const o=t[i];if(o.classList.contains("xterm"))break;if(o.classList.contains("xterm-hover"))return}this._lastBufferCell&&s.x===this._lastBufferCell.x&&s.y===this._lastBufferCell.y||(this._handleHover(s),this._lastBufferCell=s)}_handleHover(e){if(this._activeLine!==e.y||this._wasResized)return this._clearCurrentLink(),this._askForLink(e,!1),void(this._wasResized=!1);this._currentLink&&this._linkAtPosition(this._currentLink.link,e)||(this._clearCurrentLink(),this._askForLink(e,!0))}_askForLink(e,s){var t,i;this._activeProviderReplies&&s||((t=this._activeProviderReplies)===null||t===void 0||t.forEach((l=>{l==null||l.forEach((v=>{v.link.dispose&&v.link.dispose()}))})),this._activeProviderReplies=new Map,this._activeLine=e.y);let o=!1;for(const[l,v]of this._linkProviders.entries())s?!((i=this._activeProviderReplies)===null||i===void 0)&&i.get(l)&&(o=this._checkLinkProviderResult(l,e,o)):v.provideLinks(e.y,(m=>{var h,g;if(this._isMouseOut)return;const b=m==null?void 0:m.map((L=>({link:L})));(h=this._activeProviderReplies)===null||h===void 0||h.set(l,b),o=this._checkLinkProviderResult(l,e,o),((g=this._activeProviderReplies)===null||g===void 0?void 0:g.size)===this._linkProviders.length&&this._removeIntersectingLinks(e.y,this._activeProviderReplies)}))}_removeIntersectingLinks(e,s){const t=new Set;for(let i=0;i<s.size;i++){const o=s.get(i);if(o)for(let l=0;l<o.length;l++){const v=o[l],m=v.link.range.start.y<e?0:v.link.range.start.x,h=v.link.range.end.y>e?this._bufferService.cols:v.link.range.end.x;for(let g=m;g<=h;g++){if(t.has(g)){o.splice(l--,1);break}t.add(g)}}}}_checkLinkProviderResult(e,s,t){var i;if(!this._activeProviderReplies)return t;const o=this._activeProviderReplies.get(e);let l=!1;for(let v=0;v<e;v++)this._activeProviderReplies.has(v)&&!this._activeProviderReplies.get(v)||(l=!0);if(!l&&o){const v=o.find((m=>this._linkAtPosition(m.link,s)));v&&(t=!0,this._handleNewLink(v))}if(this._activeProviderReplies.size===this._linkProviders.length&&!t)for(let v=0;v<this._activeProviderReplies.size;v++){const m=(i=this._activeProviderReplies.get(v))===null||i===void 0?void 0:i.find((h=>this._linkAtPosition(h.link,s)));if(m){t=!0,this._handleNewLink(m);break}}return t}_handleMouseDown(){this._mouseDownLink=this._currentLink}_handleMouseUp(e){if(!this._element||!this._mouseService||!this._currentLink)return;const s=this._positionFromMouseEvent(e,this._element,this._mouseService);s&&this._mouseDownLink===this._currentLink&&this._linkAtPosition(this._currentLink.link,s)&&this._currentLink.link.activate(e,this._currentLink.link.text)}_clearCurrentLink(e,s){this._element&&this._currentLink&&this._lastMouseEvent&&(!e||!s||this._currentLink.link.range.start.y>=e&&this._currentLink.link.range.end.y<=s)&&(this._linkLeave(this._element,this._currentLink.link,this._lastMouseEvent),this._currentLink=void 0,(0,f.disposeArray)(this._linkCacheDisposables))}_handleNewLink(e){if(!this._element||!this._lastMouseEvent||!this._mouseService)return;const s=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);s&&this._linkAtPosition(e.link,s)&&(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:()=>{var t,i;return(i=(t=this._currentLink)===null||t===void 0?void 0:t.state)===null||i===void 0?void 0:i.decorations.pointerCursor},set:t=>{var i,o;!((i=this._currentLink)===null||i===void 0)&&i.state&&this._currentLink.state.decorations.pointerCursor!==t&&(this._currentLink.state.decorations.pointerCursor=t,this._currentLink.state.isHovered&&((o=this._element)===null||o===void 0||o.classList.toggle("xterm-cursor-pointer",t)))}},underline:{get:()=>{var t,i;return(i=(t=this._currentLink)===null||t===void 0?void 0:t.state)===null||i===void 0?void 0:i.decorations.underline},set:t=>{var i,o,l;!((i=this._currentLink)===null||i===void 0)&&i.state&&((l=(o=this._currentLink)===null||o===void 0?void 0:o.state)===null||l===void 0?void 0:l.decorations.underline)!==t&&(this._currentLink.state.decorations.underline=t,this._currentLink.state.isHovered&&this._fireUnderlineEvent(e.link,t))}}}),this._renderService&&this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange((t=>{if(!this._currentLink)return;const i=t.start===0?0:t.start+1+this._bufferService.buffer.ydisp,o=this._bufferService.buffer.ydisp+1+t.end;if(this._currentLink.link.range.start.y>=i&&this._currentLink.link.range.end.y<=o&&(this._clearCurrentLink(i,o),this._lastMouseEvent&&this._element)){const l=this._positionFromMouseEvent(this._lastMouseEvent,this._element,this._mouseService);l&&this._askForLink(l,!1)}}))))}_linkHover(e,s,t){var i;!((i=this._currentLink)===null||i===void 0)&&i.state&&(this._currentLink.state.isHovered=!0,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(s,!0),this._currentLink.state.decorations.pointerCursor&&e.classList.add("xterm-cursor-pointer")),s.hover&&s.hover(t,s.text)}_fireUnderlineEvent(e,s){const t=e.range,i=this._bufferService.buffer.ydisp,o=this._createLinkUnderlineEvent(t.start.x-1,t.start.y-i-1,t.end.x,t.end.y-i-1,void 0);(s?this._onShowLinkUnderline:this._onHideLinkUnderline).fire(o)}_linkLeave(e,s,t){var i;!((i=this._currentLink)===null||i===void 0)&&i.state&&(this._currentLink.state.isHovered=!1,this._currentLink.state.decorations.underline&&this._fireUnderlineEvent(s,!1),this._currentLink.state.decorations.pointerCursor&&e.classList.remove("xterm-cursor-pointer")),s.leave&&s.leave(t,s.text)}_linkAtPosition(e,s){const t=e.range.start.y*this._bufferService.cols+e.range.start.x,i=e.range.end.y*this._bufferService.cols+e.range.end.x,o=s.y*this._bufferService.cols+s.x;return t<=o&&o<=i}_positionFromMouseEvent(e,s,t){const i=t.getCoords(e,s,this._bufferService.cols,this._bufferService.rows);if(i)return{x:i[0],y:i[1]+this._bufferService.buffer.ydisp}}_createLinkUnderlineEvent(e,s,t,i,o){return{x1:e,y1:s,x2:t,y2:i,cols:this._bufferService.cols,fg:o}}};r.Linkifier2=u=c([_(0,p.IBufferService)],u)},9042:(I,r)=>{Object.defineProperty(r,"__esModule",{value:!0}),r.tooMuchOutput=r.promptLabel=void 0,r.promptLabel="Terminal input",r.tooMuchOutput="Too much output to announce, navigate to rows manually to read"},3730:function(I,r,a){var c=this&&this.__decorate||function(u,e,s,t){var i,o=arguments.length,l=o<3?e:t===null?t=Object.getOwnPropertyDescriptor(e,s):t;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")l=Reflect.decorate(u,e,s,t);else for(var v=u.length-1;v>=0;v--)(i=u[v])&&(l=(o<3?i(l):o>3?i(e,s,l):i(e,s))||l);return o>3&&l&&Object.defineProperty(e,s,l),l},_=this&&this.__param||function(u,e){return function(s,t){e(s,t,u)}};Object.defineProperty(r,"__esModule",{value:!0}),r.OscLinkProvider=void 0;const n=a(511),d=a(2585);let f=r.OscLinkProvider=class{constructor(u,e,s){this._bufferService=u,this._optionsService=e,this._oscLinkService=s}provideLinks(u,e){var s;const t=this._bufferService.buffer.lines.get(u-1);if(!t)return void e(void 0);const i=[],o=this._optionsService.rawOptions.linkHandler,l=new n.CellData,v=t.getTrimmedLength();let m=-1,h=-1,g=!1;for(let b=0;b<v;b++)if(h!==-1||t.hasContent(b)){if(t.loadCell(b,l),l.hasExtendedAttrs()&&l.extended.urlId){if(h===-1){h=b,m=l.extended.urlId;continue}g=l.extended.urlId!==m}else h!==-1&&(g=!0);if(g||h!==-1&&b===v-1){const L=(s=this._oscLinkService.getLinkData(m))===null||s===void 0?void 0:s.uri;if(L){const y={start:{x:h+1,y:u},end:{x:b+(g||b!==v-1?0:1),y:u}};let k=!1;if(!(o!=null&&o.allowNonHttpProtocols))try{const x=new URL(L);["http:","https:"].includes(x.protocol)||(k=!0)}catch{k=!0}k||i.push({text:L,range:y,activate:(x,T)=>o?o.activate(x,T,y):p(0,T),hover:(x,T)=>{var O;return(O=o==null?void 0:o.hover)===null||O===void 0?void 0:O.call(o,x,T,y)},leave:(x,T)=>{var O;return(O=o==null?void 0:o.leave)===null||O===void 0?void 0:O.call(o,x,T,y)}})}g=!1,l.hasExtendedAttrs()&&l.extended.urlId?(h=b,m=l.extended.urlId):(h=-1,m=-1)}}e(i)}};function p(u,e){if(confirm(`Do you want to navigate to ${e}?
4
4
 
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Remote Codex Supervisor</title>
7
- <script type="module" crossorigin src="/assets/index-BlAhoIuq.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DI0NRNgr.css">
7
+ <script type="module" crossorigin src="/assets/index-D1R9CUnx.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-BiuFei_K.css">
9
9
  </head>
10
10
  <body class="bg-stone-950">
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remote-codex",
3
- "version": "0.1.10",
3
+ "version": "0.11.1",
4
4
  "description": "Local web supervisor for Codex workspaces and threads.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,6 +17,7 @@
17
17
  "packages/agent-runtime/src/",
18
18
  "packages/claude/src/",
19
19
  "packages/codex/src/",
20
+ "packages/opencode/src/",
20
21
  "packages/db/src/",
21
22
  "packages/db/migrations/*.sql",
22
23
  "packages/shared/src/",
@@ -53,8 +54,6 @@
53
54
  "impeccable:detect:json": "impeccable detect --fast --json apps/supervisor-web/src"
54
55
  },
55
56
  "dependencies": {
56
- "@anthropic-ai/claude-agent-sdk": "0.3.146",
57
- "@anthropic-ai/sdk": "^0.97.1",
58
57
  "@fastify/multipart": "^9.0.3",
59
58
  "@fastify/websocket": "^11.0.2",
60
59
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -1,2 +1,6 @@
1
+ export * from './model-pricing';
2
+ export * from './management-errors';
1
3
  export * from './registry';
4
+ export * from './runtime-errors';
2
5
  export * from './types';
6
+ export * from './unavailable-runtime';
@@ -0,0 +1,11 @@
1
+ import type { ApiErrorShape } from '../../shared/src/index';
2
+
3
+ export class AgentRuntimeManagementError extends Error {
4
+ constructor(
5
+ public readonly statusCode: number,
6
+ public readonly payload: ApiErrorShape,
7
+ ) {
8
+ super(payload.message);
9
+ this.name = 'AgentRuntimeManagementError';
10
+ }
11
+ }
@@ -0,0 +1,325 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import type {
5
+ ThreadTurnPriceEstimateDto,
6
+ ThreadTurnTokenUsageDto,
7
+ } from '../../shared/src/index';
8
+
9
+ export type PricingTierKey = 'standard' | 'fast';
10
+
11
+ interface ModelPricingEntry {
12
+ inputUsdPerMillion: number;
13
+ cachedInputUsdPerMillion: number;
14
+ outputUsdPerMillion: number;
15
+ supportsFastMode: boolean;
16
+ fastMultiplier?: number;
17
+ contextWindowTokens?: number;
18
+ }
19
+
20
+ interface PricingTierConfig {
21
+ multiplier: number;
22
+ }
23
+
24
+ interface TurnPricingSnapshot {
25
+ pricingModelKey: string;
26
+ pricingTierKey: PricingTierKey;
27
+ }
28
+
29
+ interface PricingConfig {
30
+ currency: 'USD';
31
+ tiers: Record<PricingTierKey, PricingTierConfig>;
32
+ models: Record<string, ModelPricingEntry>;
33
+ }
34
+
35
+ const TOKEN_PRICE_DENOMINATOR = 1_000_000;
36
+ let cachedPricingConfig: PricingConfig | null = null;
37
+
38
+ function resolvePackageRoot(start = process.cwd()) {
39
+ if (process.env.REMOTE_CODEX_PACKAGE_ROOT) {
40
+ return path.resolve(process.env.REMOTE_CODEX_PACKAGE_ROOT);
41
+ }
42
+
43
+ let current = path.resolve(start);
44
+
45
+ while (current !== path.dirname(current)) {
46
+ if (fs.existsSync(path.join(current, 'pnpm-workspace.yaml'))) {
47
+ return current;
48
+ }
49
+ current = path.dirname(current);
50
+ }
51
+
52
+ throw new Error('Unable to locate package root for model pricing config.');
53
+ }
54
+
55
+ function getPricingConfigPath() {
56
+ return path.join(resolvePackageRoot(), 'config', 'codex-model-pricing.json');
57
+ }
58
+
59
+ function isPositiveNumber(value: unknown) {
60
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
61
+ }
62
+
63
+ function parsePricingConfig(raw: unknown): PricingConfig {
64
+ if (!raw || typeof raw !== 'object') {
65
+ throw new Error('Pricing config must be a JSON object.');
66
+ }
67
+
68
+ const config = raw as {
69
+ currency?: unknown;
70
+ tiers?: unknown;
71
+ models?: unknown;
72
+ };
73
+
74
+ if (config.currency !== 'USD') {
75
+ throw new Error('Pricing config currency must be "USD".');
76
+ }
77
+
78
+ if (!config.tiers || typeof config.tiers !== 'object') {
79
+ throw new Error('Pricing config must include a "tiers" object.');
80
+ }
81
+ if (!config.models || typeof config.models !== 'object') {
82
+ throw new Error('Pricing config must include a "models" object.');
83
+ }
84
+
85
+ const tiersSource = config.tiers as Record<string, unknown>;
86
+ const modelsSource = config.models as Record<string, unknown>;
87
+
88
+ const tiers: Record<PricingTierKey, PricingTierConfig> = {
89
+ standard: {
90
+ multiplier: 1,
91
+ },
92
+ fast: {
93
+ multiplier: 1,
94
+ },
95
+ };
96
+
97
+ for (const tierKey of ['standard', 'fast'] as const) {
98
+ const value = tiersSource[tierKey];
99
+ if (!value || typeof value !== 'object') {
100
+ throw new Error(`Pricing config tier "${tierKey}" is missing or invalid.`);
101
+ }
102
+
103
+ const multiplier = (value as { multiplier?: unknown }).multiplier;
104
+ if (!isPositiveNumber(multiplier)) {
105
+ throw new Error(`Pricing config tier "${tierKey}" multiplier must be a non-negative number.`);
106
+ }
107
+
108
+ tiers[tierKey] = {
109
+ multiplier: multiplier as number,
110
+ };
111
+ }
112
+
113
+ const models: Record<string, ModelPricingEntry> = {};
114
+ for (const [modelKey, value] of Object.entries(modelsSource)) {
115
+ if (!value || typeof value !== 'object') {
116
+ throw new Error(`Pricing config model "${modelKey}" is invalid.`);
117
+ }
118
+
119
+ const entry = value as {
120
+ inputUsdPerMillion?: unknown;
121
+ cachedInputUsdPerMillion?: unknown;
122
+ outputUsdPerMillion?: unknown;
123
+ supportsFastMode?: unknown;
124
+ fastMultiplier?: unknown;
125
+ contextWindowTokens?: unknown;
126
+ };
127
+
128
+ if (
129
+ !isPositiveNumber(entry.inputUsdPerMillion) ||
130
+ !isPositiveNumber(entry.cachedInputUsdPerMillion) ||
131
+ !isPositiveNumber(entry.outputUsdPerMillion) ||
132
+ typeof entry.supportsFastMode !== 'boolean'
133
+ ) {
134
+ throw new Error(`Pricing config model "${modelKey}" has invalid fields.`);
135
+ }
136
+ if (
137
+ entry.fastMultiplier !== undefined &&
138
+ !isPositiveNumber(entry.fastMultiplier)
139
+ ) {
140
+ throw new Error(`Pricing config model "${modelKey}" fastMultiplier must be a non-negative number.`);
141
+ }
142
+ if (
143
+ entry.contextWindowTokens !== undefined &&
144
+ !isPositiveNumber(entry.contextWindowTokens)
145
+ ) {
146
+ throw new Error(`Pricing config model "${modelKey}" contextWindowTokens must be a non-negative number.`);
147
+ }
148
+
149
+ models[modelKey] = {
150
+ inputUsdPerMillion: entry.inputUsdPerMillion as number,
151
+ cachedInputUsdPerMillion: entry.cachedInputUsdPerMillion as number,
152
+ outputUsdPerMillion: entry.outputUsdPerMillion as number,
153
+ supportsFastMode: entry.supportsFastMode,
154
+ ...(entry.fastMultiplier !== undefined
155
+ ? { fastMultiplier: entry.fastMultiplier as number }
156
+ : {}),
157
+ ...(entry.contextWindowTokens !== undefined
158
+ ? { contextWindowTokens: entry.contextWindowTokens as number }
159
+ : {}),
160
+ };
161
+ }
162
+
163
+ return {
164
+ currency: 'USD',
165
+ tiers,
166
+ models,
167
+ };
168
+ }
169
+
170
+ function getPricingConfig() {
171
+ if (cachedPricingConfig) {
172
+ return cachedPricingConfig;
173
+ }
174
+
175
+ const configPath = getPricingConfigPath();
176
+ const content = fs.readFileSync(configPath, 'utf8');
177
+ cachedPricingConfig = parsePricingConfig(JSON.parse(content) as unknown);
178
+ return cachedPricingConfig;
179
+ }
180
+
181
+ export function resetPricingConfigCacheForTest() {
182
+ cachedPricingConfig = null;
183
+ }
184
+
185
+ export function pricingTierForFastMode(fastMode: boolean): PricingTierKey {
186
+ return fastMode ? 'fast' : 'standard';
187
+ }
188
+
189
+ function pricingModelKeyForModel(model: string | null | undefined) {
190
+ const modelKey = model?.trim();
191
+ if (!modelKey) {
192
+ return null;
193
+ }
194
+
195
+ const models = getPricingConfig().models;
196
+ if (models[modelKey]) {
197
+ return modelKey;
198
+ }
199
+
200
+ const providerSeparatorIndex = modelKey.indexOf('/');
201
+ const unqualifiedModelKey = providerSeparatorIndex >= 0
202
+ ? modelKey.slice(providerSeparatorIndex + 1)
203
+ : null;
204
+ if (unqualifiedModelKey && models[unqualifiedModelKey]) {
205
+ return unqualifiedModelKey;
206
+ }
207
+
208
+ for (const candidate of [modelKey, unqualifiedModelKey]) {
209
+ if (!candidate) {
210
+ continue;
211
+ }
212
+ const claudeDateSuffixMatch = candidate.match(/^(claude-[a-z]+-\d+(?:-\d+)?)-20\d{6}$/);
213
+ if (claudeDateSuffixMatch?.[1] && models[claudeDateSuffixMatch[1]]) {
214
+ return claudeDateSuffixMatch[1];
215
+ }
216
+ }
217
+
218
+ return modelKey;
219
+ }
220
+
221
+ export function supportsFastMode(model: string | null | undefined) {
222
+ const pricingModelKey = pricingModelKeyForModel(model);
223
+ if (!pricingModelKey) {
224
+ return false;
225
+ }
226
+
227
+ return getPricingConfig().models[pricingModelKey]?.supportsFastMode === true;
228
+ }
229
+
230
+ export function contextWindowForModel(model: string | null | undefined) {
231
+ const pricingModelKey = pricingModelKeyForModel(model);
232
+ if (!pricingModelKey) {
233
+ return null;
234
+ }
235
+
236
+ const contextWindow = getPricingConfig().models[pricingModelKey]?.contextWindowTokens;
237
+ return typeof contextWindow === 'number' && contextWindow > 0
238
+ ? contextWindow
239
+ : null;
240
+ }
241
+
242
+ export function buildTurnPricingSnapshot(
243
+ model: string | null | undefined,
244
+ fastMode: boolean,
245
+ ): TurnPricingSnapshot | null {
246
+ const pricingModelKey = pricingModelKeyForModel(model);
247
+ if (!pricingModelKey) {
248
+ return null;
249
+ }
250
+
251
+ return {
252
+ pricingModelKey,
253
+ pricingTierKey: pricingTierForFastMode(fastMode),
254
+ };
255
+ }
256
+
257
+ export function estimateTurnPrice(
258
+ usage: ThreadTurnTokenUsageDto | null | undefined,
259
+ snapshot:
260
+ | {
261
+ pricingModelKey: string | null | undefined;
262
+ pricingTierKey: PricingTierKey | string | null | undefined;
263
+ }
264
+ | null
265
+ | undefined,
266
+ ): ThreadTurnPriceEstimateDto | null {
267
+ if (!usage?.total) {
268
+ return null;
269
+ }
270
+
271
+ const pricingModelKey = pricingModelKeyForModel(snapshot?.pricingModelKey);
272
+ if (!pricingModelKey) {
273
+ return null;
274
+ }
275
+
276
+ const pricingConfig = getPricingConfig();
277
+ const modelPricing = pricingConfig.models[pricingModelKey];
278
+ if (!modelPricing) {
279
+ return null;
280
+ }
281
+
282
+ const tierKey =
283
+ snapshot?.pricingTierKey === 'fast' ? 'fast' : snapshot?.pricingTierKey === 'standard'
284
+ ? 'standard'
285
+ : null;
286
+ if (!tierKey) {
287
+ return null;
288
+ }
289
+
290
+ const tier = pricingConfig.tiers[tierKey];
291
+ if (!tier) {
292
+ return null;
293
+ }
294
+
295
+ const nonCachedInputTokens = Math.max(
296
+ usage.total.inputTokens - usage.total.cachedInputTokens,
297
+ 0,
298
+ );
299
+ const cachedInputTokens = Math.max(usage.total.cachedInputTokens, 0);
300
+ const outputTokens = Math.max(usage.total.outputTokens, 0);
301
+ const multiplier =
302
+ tierKey === 'fast' && modelPricing.fastMultiplier !== undefined
303
+ ? modelPricing.fastMultiplier
304
+ : tier.multiplier;
305
+
306
+ const inputUsd =
307
+ (nonCachedInputTokens * modelPricing.inputUsdPerMillion * multiplier) /
308
+ TOKEN_PRICE_DENOMINATOR;
309
+ const cachedInputUsd =
310
+ (cachedInputTokens * modelPricing.cachedInputUsdPerMillion * multiplier) /
311
+ TOKEN_PRICE_DENOMINATOR;
312
+ const outputUsd =
313
+ (outputTokens * modelPricing.outputUsdPerMillion * multiplier) /
314
+ TOKEN_PRICE_DENOMINATOR;
315
+
316
+ return {
317
+ pricingModelKey,
318
+ pricingTierKey: tierKey,
319
+ currency: pricingConfig.currency,
320
+ inputUsd,
321
+ cachedInputUsd,
322
+ outputUsd,
323
+ totalUsd: inputUsd + cachedInputUsd + outputUsd,
324
+ };
325
+ }
@@ -1,3 +1,6 @@
1
+ import {
2
+ defaultAgentBackendId,
3
+ } from '../../shared/src/index';
1
4
  import {
2
5
  AgentProviderId,
3
6
  AgentRuntime,
@@ -7,7 +10,10 @@ import {
7
10
  export class AgentRuntimeRegistry {
8
11
  private readonly runtimes = new Map<AgentProviderId, AgentRuntime>();
9
12
 
10
- constructor(runtimes: AgentRuntime[]) {
13
+ constructor(
14
+ runtimes: AgentRuntime[],
15
+ private readonly defaultProvider: AgentProviderId = defaultAgentBackendId,
16
+ ) {
11
17
  for (const runtime of runtimes) {
12
18
  this.runtimes.set(runtime.provider, runtime);
13
19
  }
@@ -30,15 +36,24 @@ export class AgentRuntimeRegistry {
30
36
  }
31
37
 
32
38
  list(): AgentRuntimeDescriptor[] {
33
- return this.all().map((runtime, index) => ({
39
+ return this.all().map((runtime) => ({
34
40
  provider: runtime.provider,
35
41
  displayName: runtime.displayName,
36
42
  description: runtime.description,
37
- enabled: true,
38
- isDefault: index === 0,
43
+ enabled: isAgentRuntimeEnabled(runtime),
44
+ isDefault: runtime.provider === this.defaultProvider,
39
45
  status: runtime.getStatus(),
40
46
  capabilities: runtime.capabilities,
41
47
  managementSchema: runtime.managementSchema,
48
+ installation: runtime.installation,
42
49
  }));
43
50
  }
44
51
  }
52
+
53
+ export function isAgentRuntimeEnabled(runtime: Pick<AgentRuntime, 'capabilities' | 'installation'>) {
54
+ return (
55
+ runtime.installation.installed &&
56
+ runtime.capabilities.sessions.resume &&
57
+ runtime.capabilities.turns.start
58
+ );
59
+ }
@@ -0,0 +1,97 @@
1
+ import { AgentRuntimeError } from './types';
2
+
3
+ export type TurnSteerRace =
4
+ | { type: 'missing' }
5
+ | { type: 'turnIdMismatch'; actualTurnId: string };
6
+
7
+ function isRecord(value: unknown): value is Record<string, unknown> {
8
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
9
+ }
10
+
11
+ function stringField(value: unknown, key: string) {
12
+ return isRecord(value) && typeof value[key] === 'string' ? value[key] : null;
13
+ }
14
+
15
+ function remoteErrorMessage(error: unknown) {
16
+ if (error instanceof AgentRuntimeError) {
17
+ return error.message;
18
+ }
19
+ return error instanceof Error ? error.message : null;
20
+ }
21
+
22
+ export function parseTurnSteerRace(error: unknown): TurnSteerRace | null {
23
+ if (error instanceof AgentRuntimeError) {
24
+ const raceType = stringField(error.details, 'turnSteerRace');
25
+ if (raceType === 'missing') {
26
+ return { type: 'missing' };
27
+ }
28
+ if (raceType === 'turnIdMismatch') {
29
+ const actualTurnId = stringField(error.details, 'actualTurnId');
30
+ if (actualTurnId) {
31
+ return { type: 'turnIdMismatch', actualTurnId };
32
+ }
33
+ }
34
+ }
35
+
36
+ const message = remoteErrorMessage(error);
37
+ if (!message) {
38
+ return null;
39
+ }
40
+
41
+ if (message === 'no active turn to steer') {
42
+ return { type: 'missing' };
43
+ }
44
+
45
+ const mismatchPrefix = 'expected active turn id `';
46
+ const mismatchSeparator = '` but found `';
47
+ if (!message.startsWith(mismatchPrefix)) {
48
+ return null;
49
+ }
50
+
51
+ const actualTurnId = message
52
+ .slice(mismatchPrefix.length)
53
+ .split(mismatchSeparator)[1]
54
+ ?.replace(/`$/, '');
55
+
56
+ if (!actualTurnId) {
57
+ return null;
58
+ }
59
+
60
+ return {
61
+ type: 'turnIdMismatch',
62
+ actualTurnId,
63
+ };
64
+ }
65
+
66
+ export function isRuntimeRequestError(error: unknown) {
67
+ return error instanceof AgentRuntimeError;
68
+ }
69
+
70
+ export function isRemoteThreadBootstrapError(error: unknown) {
71
+ if (!(error instanceof AgentRuntimeError)) {
72
+ return false;
73
+ }
74
+
75
+ return (
76
+ error.message.includes('includeTurns is unavailable before first user message') ||
77
+ error.message.includes('is not materialized yet') ||
78
+ error.message.includes('no rollout found for thread id') ||
79
+ error.message.includes('failed to load rollout') ||
80
+ (error.message.includes('rollout at') && error.message.includes('is empty'))
81
+ );
82
+ }
83
+
84
+ export function isUnsupportedHooksListError(error: unknown) {
85
+ if (!(error instanceof AgentRuntimeError)) {
86
+ return false;
87
+ }
88
+
89
+ const remoteCode = isRecord(error.details) ? error.details.code : null;
90
+ const message = error.message.toLowerCase();
91
+ return (
92
+ remoteCode === -32601 ||
93
+ message.includes('endpoint not found') ||
94
+ message.includes('method not found') ||
95
+ (message.includes('hooks/list') && message.includes('not found'))
96
+ );
97
+ }
@@ -1,7 +1,15 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import type { ThreadHistoryItemDto } from '../../shared/src/index';
2
+ import type {
3
+ AgentBackendIdDto,
4
+ AgentBackendInstallationDto,
5
+ ThreadHistoryItemDto,
6
+ } from '../../shared/src/index';
3
7
 
4
- export type AgentProviderId = 'codex' | 'claude';
8
+ export const transientAgentHistoryItemSymbol: unique symbol = Symbol(
9
+ 'remoteCodex.transientAgentHistoryItem',
10
+ );
11
+
12
+ export type AgentProviderId = AgentBackendIdDto;
5
13
 
6
14
  export type AgentRuntimeErrorCode =
7
15
  | 'provider_unavailable'
@@ -84,6 +92,7 @@ export interface AgentRuntimeDescriptor {
84
92
  status: AgentRuntimeStatus;
85
93
  capabilities: AgentProviderCapabilities;
86
94
  managementSchema: AgentRuntimeManagementSchema;
95
+ installation: AgentBackendInstallationDto;
87
96
  }
88
97
 
89
98
  export interface AgentRuntimeConfigFileSchema {
@@ -142,6 +151,7 @@ export interface AgentModel {
142
151
  description: string;
143
152
  isDefault: boolean;
144
153
  hidden: boolean;
154
+ supportsPerformanceMode?: boolean;
145
155
  supportedReasoningEfforts: Array<{
146
156
  reasoningEffort: string;
147
157
  description: string;
@@ -169,7 +179,26 @@ export interface AgentSessionSummary {
169
179
  rawSession?: unknown;
170
180
  }
171
181
 
172
- export type AgentHistoryItem = ThreadHistoryItemDto;
182
+ export type AgentHistoryItem = ThreadHistoryItemDto & {
183
+ [transientAgentHistoryItemSymbol]?: true;
184
+ };
185
+
186
+ export function markTransientAgentHistoryItem<T extends ThreadHistoryItemDto>(
187
+ item: T,
188
+ ): T & AgentHistoryItem {
189
+ Object.defineProperty(item, transientAgentHistoryItemSymbol, {
190
+ value: true,
191
+ enumerable: false,
192
+ configurable: true,
193
+ });
194
+ return item as T & AgentHistoryItem;
195
+ }
196
+
197
+ export function isTransientAgentHistoryItem(
198
+ item: ThreadHistoryItemDto,
199
+ ): item is AgentHistoryItem & { [transientAgentHistoryItemSymbol]: true } {
200
+ return Boolean((item as AgentHistoryItem)[transientAgentHistoryItemSymbol]);
201
+ }
173
202
 
174
203
  export type AgentTurnItem = AgentHistoryItem;
175
204
 
@@ -191,6 +220,8 @@ export interface AgentSessionDetail extends AgentSessionSummary {
191
220
  export interface ReadAgentSessionOptions {
192
221
  limit?: number;
193
222
  beforeTurnId?: string | null;
223
+ localThreadId?: string;
224
+ workspacePath?: string;
194
225
  }
195
226
 
196
227
  export interface StartAgentSessionInput {
@@ -221,6 +252,7 @@ export interface ResumeAgentSessionInput {
221
252
  export interface StartAgentTurnInput {
222
253
  providerSessionId: string;
223
254
  prompt: string;
255
+ displayPrompt?: string | null;
224
256
  model?: string | null;
225
257
  reasoningEffort?: string | null;
226
258
  collaborationMode?: 'default' | 'plan' | null;
@@ -505,6 +537,7 @@ export interface AgentRuntime extends EventEmitter {
505
537
  readonly description: string;
506
538
  readonly capabilities: AgentProviderCapabilities;
507
539
  readonly managementSchema: AgentRuntimeManagementSchema;
540
+ readonly installation: AgentBackendInstallationDto;
508
541
 
509
542
  getStatus(): AgentRuntimeStatus;
510
543
  start(): Promise<void>;