typebulb 0.23.3 → 0.23.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/agents/claude/client.js +1 -1
- package/dist/agents/pi/matchu-patchu.ts +1 -1
- package/dist/index.js +177 -177
- package/dist/servers.js +74 -74
- package/package.json +1 -1
|
@@ -1379,7 +1379,7 @@ ${rCt(m)}`};let v=nCt(d.code,{jsxImportSource:g.ts?.jsxImportSource});if(v.error
|
|
|
1379
1379
|
`)}applyUser(o){let a=this.messages[this.messages.length-1];if(a&&a.role==="user"){this.#l(a,o.text),a.copy?a.copy.setText(a.text):a.text&&(a.copy=this.#a(a.text));return}this.#f({id:++this.#e,role:"user",text:o.text,thinking:"",tools:[]})}applyAssistant(o){let a=this.#f({id:++this.#e,role:"assistant",text:o.text,thinking:o.thinking,tools:o.tools.map(g=>({...g,isError:!1}))}),d=this.messages[this.messages.length-2];if(a.turnCopy=d?.role==="assistant"&&d.turnCopy||this.#a(""),a.turnCopy.setText(this.#h()),this.#u(a,o.text),this.#d(),o.live)for(let g of o.tools)bvn.has(g.name)&&this.openTools.add(g.id)}#u(o,a){let d=Fxe(a);d.some(g=>g.kind==="bulb")&&(o.body=d.map(g=>{if(g.kind==="md")return g.text;let m=new zre(g.source,`embed-${this.#t++}`);return this.bulbEmbeds.push(m),m}))}#d(){let o=this.bulbEmbeds.map(g=>g.name),a=fSt(o),d=hSt(o);this.#i=new Set(this.bulbEmbeds.filter((g,m)=>a[m])),this.bulbEmbeds.forEach((g,m)=>{g.setChainPosition(d[m]),g.setMounted(!a[m]||this.expandedEmbeds.has(g.key))})}#p(o){Hxe(this.expandedEmbeds,o),this.#d(),this.update()}applyToolResult(o){let a=this.#g(o.id);a&&(a.result=o.content,a.isError=o.isError,a.digest=o.digest)}applyFork(o){let a=this.#m(o.events);this.#f({id:++this.#e,role:"fork",text:"",thinking:"",tools:[],fork:{count:o.count,sub:a}})}#m(o){let a=[];for(let d of o)if(d.type==="user"){let g=a[a.length-1];g&&g.role==="user"?this.#l(g,d.text):a.push({id:++this.#e,role:"user",text:d.text,thinking:"",tools:[]})}else if(d.type==="assistant")a.push({id:++this.#e,role:"assistant",text:d.text,thinking:d.thinking,tools:d.tools.map(g=>({...g,isError:!1}))});else if(d.type==="tool_result"){let g=a.flatMap(m=>m.tools).find(m=>m.id===d.id);g&&(g.result=d.content,g.isError=d.isError,g.digest=d.digest)}return a}#g(o){return this.messages.flatMap(a=>a.tools).find(a=>a.id===o)}scrollSoon(){requestAnimationFrame(()=>{this.scrollEl&&this.#n&&(this.scrollEl.scrollTop=this.scrollEl.scrollHeight)})}onScroll(){let o=this.scrollEl;o&&(this.#n=yF(o,50))}view(){return en({class:"messages",onScroll:()=>this.onScroll(),onMounted:o=>{this.scrollEl=o}},this.parent.ready?this.renderMessages():en({class:"note"},"Connecting\u2026"))}renderMessages(){let o=[],a=-1;for(let m of this.messages)m.role==="user"||o.length===0?(m.role==="user"&&a++,o.push({idx:Math.max(0,a),msgs:[m]})):o[o.length-1].msgs.push(m);let d=o.flatMap((m,v)=>this.renderTurn(m.msgs,m.idx,v===o.length-1));d.unshift(this.#w());let g=this.parent.draft;return g?d.push(this.#A(g,Math.max(0,a))):(this.#r.clear(),this.#o=!1),d}#w(){return en({class:"masthead",key:"masthead"},Fee({class:"masthead-logo light",src:lvn,alt:"typebulb"}),Fee({class:"masthead-logo dark",src:fvn,alt:"typebulb"}),en({class:"masthead-tagline"},"a live mirror of your agent\u2019s session, with embedded bulbs, latex, svg, mermaid and more"))}#A(o,a){let d=`draft-${o.text.length}-${o.thinking.length}`;return o.text.length<this.#s&&this.#r.clear(),this.#s=o.text.length,en({class:["bubble","assistant","draft",qee(a)],key:d},!this.parent.prose&&o.thinking?Oye({class:"thinking",open:this.#o,onToggle:g=>{this.#o=g.currentTarget.open}},Rye("thinking"),e6(o.thinking)):null,o.text.trim()?this.#v(d,o.text):en({class:"draft-wait shimmer-text"},"\u2026"))}#v(o,a){let d=Fxe(a);return d.some(g=>g.kind==="bulb")?d.map((g,m)=>g.kind==="md"?g.text.trim()?this.#b(`${o}-md-${m}`,ZM(g.text)):null:this.#k(g.source,m)):this.#b(o,ZM(a))}#k(o,a){let d=bH(o),g=o.split(`
|
|
1380
1380
|
`).length;return en({class:"md",key:`draft-bulb-${a}`},en({class:"embed bulb-streaming"},en({class:"bulb-streaming-head"},Ji("\u{1F4A1} "),Ji({class:"shimmer-text shimmer-slow"},`${d?`${d} \u2014 `:""}writing\u2026`),Ji({class:"bulb-streaming-count"},`${g} lines`)),en({class:["bulb-code","md"],onScroll:m=>{let v=m.currentTarget;this.#r.set(a,{top:v.scrollTop,stuck:yF(v,50)})},onMounted:m=>{m.innerHTML=Jre.render(mH(o));let v=this.#r.get(a);m.scrollTop=v&&!v.stuck?v.top:m.scrollHeight}})))}renderTurn(o,a,d){if(this.parent.prose){let T=o.filter(D=>D.role==="user"||D.role==="fork"||D.text||D.body),L=[...T].reverse().find(D=>D.role==="assistant"&&!!D.text);return T.map(D=>{if(D.role==="fork")return this.forkStub(D,a);let P=D.role==="user"?D.copy:D===L?D.turnCopy:void 0;return this.bubble(D,a,P??null)})}let g=o.filter(T=>T.role==="assistant");if(d||g.length<2)return o.map(T=>T.role==="fork"?this.forkStub(T,a):this.bubble(T,a));let m=this.expandedTurns.has(a),v=g.slice(0,-1),w=g[g.length-1],I=o.filter(T=>T.role==="user").map(T=>this.bubble(T,a));for(let T of o)T.role==="fork"&&I.push(this.forkStub(T,a));if(I.push(this.turnSummary(v,a)),m)for(let T of v)I.push(this.bubble(T,a));return I.push(this.bubble(w,a)),I}#y(o,a,d,g,m,v){let w=d.has(g);return en({class:["bubble","assistant",qee(a)],key:o},en({class:"turn-summary",onClick:()=>{Hxe(d,g),this.update()}},$xe(w),Ji({class:"turn-summary-text"},m)),v??null)}forkStub(o,a){let d=o.fork,g=this.expandedForks.has(o.id)?en({class:"fork-body"},d.sub.map(v=>this.bubble(v,a,void 0,!1))):void 0,m=[pvn(),` ${d.count} message${d.count===1?"":"s"} on an abandoned branch`];return this.#y(`fork-${o.id}`,a,this.expandedForks,o.id,m,g)}turnSummary(o,a){return this.#y(`summary-${a}`,a,this.expandedTurns,a,vvn(o))}bubble(o,a,d=o.copy,g=!0){let m=this.parent.prose,v=o.role==="assistant"&&!o.text&&!o.thinking&&o.tools.length>0;return en({class:["bubble",o.role,v?"tools-only":"",g?qee(a):""],key:o.id},!m&&o.thinking?Oye({class:"thinking"},Rye("thinking"),e6(o.thinking)):null,this.#C(o),o.role==="user"?this.#x(o):null,m?null:o.tools.map(w=>this.tool(w)),d?d.view():null)}#x(o){let d=[...o.text.matchAll(avn)].map(g=>g[1]).map(g=>this.#E(g)).filter(g=>!!g);return d.length?en({class:"paste-thumbs"},d.map(g=>Fee({class:"paste-thumb",src:g,alt:"pasted image"}))):null}#E(o){let a=this.#c.get(o);if(!(a==="pending"||a==="failed")){if(a)return a;this.#c.set(o,"pending"),(async()=>{try{let d=await tb.server.composerPasteRead(o);this.#c.set(o,d?.ok?`data:${d.mime};base64,${d.base64}`:"failed"),d?.ok&&(this.update(),this.scrollSoon())}catch{this.#c.set(o,"failed")}})()}}#C(o){return o.body?o.body.flatMap((a,d)=>typeof a=="string"?a.trim()?[this.#b(`md-${o.id}-${d}`,ZM(a))]:[]:this.#I(a)):o.text?this.#b(`md-${o.id}`,o.role==="user"?lSt(o):ZM(o.text)):null}#I(o){if(!this.#i.has(o))return[o.view()];let a=this.expandedEmbeds.has(o.key),d=en({class:"md",key:`fold-${o.key}`},en({class:"bulb-fold",onClick:()=>this.#p(o.key)},$xe(a),Ji({class:"bulb-fold-text"},`${o.name??"bulb"} \u2014 Version ${o.chainPosition}`),Ji({class:"bulb-fold-app"},"\u{1F4A1}")));return a?[d,o.view()]:[d]}#b(o,a){return en({class:"md",key:o,onMounted:a})}tool(o){let a=this.openTools.has(o.id),d=mvn(o.name,o.input),g=mSt(o),m=d?l6t(d,this.parent.cwd):dvn(hvn(o.input));return en({class:["tool",o.isError?"err":""]},en({class:"tool-head"},en({class:"tool-label"},Ji({class:"tool-name",...o.name.startsWith("mcp__")?{title:o.name}:{}},Qxe(o.name)),m?d?oM({class:"tool-sum link",title:d,onClick:v=>{v.preventDefault(),tb.server.openFile(d)}},m):Ji({class:"tool-sum"},m):null),o.result===void 0?Ji({class:"tool-run"},"\u2026"):null),o.result!==void 0?en({class:["tool-digest",a?"open":""],onClick:()=>{Hxe(this.openTools,o.id),this.update()}},$xe(a),(g?Avn(g):o.digest)||"(no output)"):null,a?en({class:"tool-card"},this.toolBody(o),o.result!==void 0&&(o.isError||!(g||bSt(o).length&&o.result.trim()===o.digest))?e6({class:"tool-out"},o.result.slice(0,4e3)):null):null)}toolBody(o){let a=mSt(o);if(a)return en({class:"todo-list"},a.map(m=>en({class:["todo",m.status??""]},Ji({class:"todo-icon"},m.status==="completed"?"\u2714":m.status==="in_progress"?"\u25FC":"\u25FB"),Ji({class:"todo-text"},m.content??""))));let d=bSt(o);if(d.length)return en({class:"tool-in"},d.map(gSt));let g=wvn(o);if(!g){let m=Object.entries(o.input??{});return m.length?en({class:"tool-in"},m.map(([v,w])=>en({class:"tool-field"},Ji({class:"tool-key"},`${v}:`),typeof w=="string"&&wSt(w)?gSt(w):e6({class:"tool-val"},typeof w=="string"?w:JSON.stringify(w,null,2))))):null}return en({class:"diff"},...g.flatMap((m,v)=>[g.length>1?en({class:"diff-step"},`edit ${v+1}/${g.length}`):null,m.old?e6({class:"diff-old"},String(m.old)):null,m.new?e6({class:"diff-new"},String(m.new)):null]))}};var Wre=class extends Ia{ready=!1;cwd="";sessionId=null;sessionPicker=new Kee;tokenPill=new Wee;bulbsPill=new Yee;prosePill=new Xee;messageList=new Kre;tokens={in:0,out:0,cached:0,cacheCreate:0};cost=0;stats=null;working=!1;latestModel=null;driverModel=null;busy=[];prose=!1;ownPid=0;pills;composer;draft=null;#e=0;#t=!1;#i=!1;#n;#r;#s;constructor(o){super(),this.pills=o.pills,this.composer=o.composer,this.#n=o.title,this.#r=o.overlays??[],this.#s=o.onPollTick}onAttached(){this.#i||(this.#i=!0,this.init())}closePopups(o){this.sessionPicker!==o&&this.sessionPicker.close(),this.bulbsPill!==o&&this.bulbsPill.close();for(let a of this.pills)a!==o&&a.close?.()}async init(){let o=await tb.server.info();this.cwd=o.cwd,this.ownPid=o.pid??0,this.composer&&(this.composer.enabled=!!o.composer),this.ready=!0,this.updateTitle(),this.update(),this.pump()}updateTitle(){let o=jye(this.cwd),a=this.sessionPicker.currentPreview(),d=Uee(a,40);document.title=d&&o?`${d} \u2014 ${o}`:d||(o?`${this.#n} \u2014 ${o}`:this.#n)}pump(){if(this.#t)return;this.#t=!0;let o=async()=>{try{let{events:a,cursor:d,working:g,latestModel:m,composer:v,busy:w}=await tb.server.poll(this.#e);this.#e=d;for(let F of a)this.apply(F);let I=g!==this.working;this.working=g;let T=Array.isArray(w)?w:[],L=T.join(`
|
|
1381
1381
|
`)!==this.busy.join(`
|
|
1382
|
-
`);this.busy=T;let D=m!==this.latestModel;this.latestModel=m??null;let P=this.composer&&v?this.composer.syncFromPoll(v):!1;(a.length||I||D||P||L)&&this.update(),(a.length||P)&&this.messageList.scrollSoon(),this.#s?.()}catch(a){console.error("[mirror] poll failed",a)}setTimeout(o,600)};o()}apply(o){switch(o.type){case"cleared":this.messageList.clear(),this.tokens={in:0,out:0,cached:0,cacheCreate:0},this.cost=0;break;case"session":this.sessionId=o.sessionId,this.updateTitle();break;case"user":this.messageList.applyUser(o);break;case"assistant":this.messageList.applyAssistant(o);break;case"tool_result":this.messageList.applyToolResult(o);break;case"fork":this.messageList.applyFork(o);break;case"usage":this.tokens={in:o.in,out:o.out,cached:o.cached,cacheCreate:o.cacheCreate},this.cost+=o.cost??0;break}}view(){return en({class:"app"},en({class:"chat"},this.messageList.view(),...this.#r.map(o=>o()),this.statusbar()),this.composer?.enabled?this.composer.view():null)}statusbar(){return en({class:"statusbar"},en({class:"statusbar-actions"},this.prosePill.view(),...this.pills.map(o=>o.view()),this.tokenPill.view(),this.sessionPicker.view(),this.bulbsPill.view()))}};var yvn=[[0,"Low"],[1,"Med"],[2,"High"]],kvn=1,Yre=s=>s?.message??String(s),xvn=()=>o6t({viewBox:"0 0 24 24",width:"15",height:"15",class:"anthropic-glyph",fill:"currentColor"},s6t({d:"M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z"})),ASt=s=>s===!0?"ok":s===!1?"bad":"warn",Xre=class extends S7{models=[];hasKey=!0;loaded=!1;current={active:!1,managed:!1,model:null,port:null,provider:null,routedModel:null,caching:"unknown",reasoning:null,externalBaseUrl:null};busy=!1;err=null;enteringKey=!1;keyDraft="";probes={};probing=null;openDiag=null;infoOpen=!1;ticking=!1;keepOpenSelector=".model-wrap";filterId="model-filter";listSelector="#model-list";filterNoun="model";search(){return Promise.resolve([])}modeToggle(){return null}onActivate(o){let a=this.rows()[o];a&&(a.kind==="default"?this.clear():a.kind==="unlock"?this.beginKeyEntry():this.set(a.id))}onAttached(){this.refresh()}async refresh(){try{let[o,a]=await Promise.all([tb.server.listSwitchModels(),tb.server.switchState()]);this.models=o.models,this.hasKey=o.hasKey,this.current=a,this.err=null}catch(o){this.err=Yre(o),console.error("[mirror] switcher refresh failed",o)}finally{this.loaded=!0,this.update()}}async tickState(){if(!(this.ticking||this.enteringKey)){this.ticking=!0;try{let o=await tb.server.switchState(),a=o.active!==this.current.active||o.model!==this.current.model||o.caching!==this.current.caching||o.routedModel!==this.current.routedModel||o.externalBaseUrl!==this.current.externalBaseUrl||o.provider!==this.current.provider||o.reasoning!==this.current.reasoning;this.current=o,a&&this.update()}catch{}finally{this.ticking=!1}}}rows(){let o=[];if(!this.hasKey)o.push({kind:"unlock"});else{let a=this.filter.trim().toLowerCase(),d=null;for(let g of this.models){if(a&&!g.label.toLowerCase().includes(a)&&!g.id.toLowerCase().includes(a))continue;let m={kind:"model",id:g.id,label:g.label,active:this.current.active&&this.current.model===g.id};m.active?d=m:o.push(m)}d&&o.push(d)}return o.push({kind:"default",active:!this.current.active&&!this.current.externalBaseUrl}),o}activeIndex(){let o=this.rows(),a=o.findIndex(d=>d.active);return a<0?Math.max(0,o.length-1):a}async show(){this.beginOpen(),this.refreshList(this.activeIndex()),this.focusFilter(),await this.refresh(),this.refreshList(this.activeIndex()),this.armClose()}onClosed(){super.onClosed(),this.enteringKey=!1,this.keyDraft="",this.openDiag=null,this.infoOpen=!1,this.err=null}async probe(o){if(!this.probing){this.probing=o,this.update();try{this.probes[o]=await tb.server.probeModel({model:o})}catch(a){this.probes[o]={ok:!1,error:Yre(a)}}this.probing=null,this.update()}}showDiag(o){this.openDiag=o,this.update()}closeDiag(){this.openDiag=null,this.update(),this.focusFilter()}label(o){return o?this.models.find(a=>a.id===o)?.label||o.split("/").pop()||o:"Anthropic"}async runBusy(o,a){this.busy=!0,this.err=null,this.update();try{let d=await o();if(d?.ok===!1)return this.err=d.error||a,this.busy=!1,this.update(),!1}catch(d){return this.err=Yre(d),this.busy=!1,this.update(),!1}return this.busy=!1,!0}async set(o){await this.runBusy(()=>tb.server.setSwitchModel({model:o}),"failed to set model")&&(await this.refresh(),this.close())}async clear(){await this.runBusy(()=>tb.server.clearSwitchModel(),"failed to revert")&&(await this.refresh(),this.close())}get reasoningSel(){return this.current.reasoning??kvn}set reasoningSel(o){this.setReasoning(o)}async setReasoning(o){if(this.current.reasoning!==o){this.current={...this.current,reasoning:o},this.update();try{let a=await tb.server.setReasoning({level:o});a?.ok===!1&&(this.err=a.error||"failed to set reasoning",this.update())}catch(a){this.err=Yre(a),this.update()}}}beginKeyEntry(){this.enteringKey=!0,this.keyDraft="",this.update(),setTimeout(()=>document.getElementById("or-key-input")?.focus())}cancelKeyEntry(){this.enteringKey=!1,this.keyDraft="",this.update(),this.focusFilter()}async saveKey(){let o=this.keyDraft.trim();o&&await this.runBusy(()=>tb.server.saveOpenRouterKey({key:o}),"failed to save key")&&(this.enteringKey=!1,this.keyDraft="",await this.refresh(),this.refreshList(this.activeIndex()))}get overridden(){return this.current.active}get uncached(){return this.current.active&&this.current.caching==="uncached"}watchdogView(){return this.uncached?en({class:["model-banner","warn"]},Ji({class:"model-banner-text"},`${this.label(this.current.model)} was served uncached via OpenRouter \u2014 the full context is re-billed each turn. Probe the model to pin a provider that caches, or pick a different one.`)):null}head(){return this.current.active?en({class:"model-head"},qc({class:"model-info-toggle",onClick:o=>{o.stopPropagation(),this.infoOpen=!0,this.update()}},"Routing info"),en({class:"reasoning-ctl",title:"Reasoning sets the route\u2019s base thinking effort."},Ji({class:"reasoning-label"},"reasoning"),this.reasoningSelect())):this.current.externalBaseUrl?en({class:"model-head"},Ji({class:["model-route","warn"]},"Custom base URL set elsewhere \u2014 \u201CAnthropic (native)\u201D clears it")):null}reasoningSelect(){return i6t({target:this,prop:()=>this.reasoningSel,attrs:{class:"reasoning-select",onClick:o=>o.stopPropagation()},options:yvn.map(([o,a])=>({value:o,label:a}))})}infoView(){let o=this.label(this.current.model),a=()=>{this.infoOpen=!1,this.update()};return en({class:"picker model-picker diag-mode",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&(d.stopPropagation(),a())}},en({class:"diag-head"},Ji({class:"diag-name"},"Routing"),en({class:"diag-head-acts"},qc({class:"diag-back",title:"Back to the model list",onClick:d=>{d.stopPropagation(),a()}},"\u2190 models"))),en({class:"diag-body"},en({class:"diag-line"},`You are currently routing to ${o} via OpenRouter, not your Anthropic subscription.`),en({class:"diag-line"},"The route is shared by every Claude Code conversation scoped to this project."),en({class:"diag-line"},"Switching to or from Anthropic toggles the proxy, so for existing conversations you\u2019ll need to:"),en({class:["diag-line","diag-bullet"]},"\u2022 Relaunch the Claude CLI"),en({class:["diag-line","diag-bullet"]},"\u2022 or, in the VS Code extension, run \u201CDeveloper: Restart Extension Host\u201D (Cmd/Ctrl+Shift+P).")))}view(){let o=this.current.active,a=this.uncached,d=!o&&!!this.current.externalBaseUrl,g=this.label(this.current.model),m=a?`${g} via OpenRouter, uncached \u2014 full context re-billed each turn. Click to switch or revert.`:o?`claude \u2192 ${this.current.model}: its Anthropic API is proxied to OpenRouter. Click to switch or revert.`:d?`Custom ANTHROPIC_BASE_URL set outside this tool (${this.current.externalBaseUrl}). Click to manage.`:"Anthropic (native) \u2014 click to proxy claude\u2019s Anthropic API to an OpenRouter model.",v=o?g:d?"custom route":xvn();return en({class:"model-wrap"},qc({class:["pill",o||d?"on":"glyph",a?"warn":""],title:m,ariaLabel:o||d?void 0:"Anthropic (native)",onClick:w=>{w.stopPropagation(),this.open?this.close():this.show()}},v),this.open?this.popup():null)}popup(){if(this.enteringKey)return this.keyView();if(this.infoOpen)return this.infoView();if(this.openDiag)return this.diagView(this.openDiag);let o=this.rows(),a=this.loaded&&this.hasKey&&!this.models.length;return en({class:"picker model-picker"},this.head(),en({id:"model-list",class:"picker-list",onScroll:()=>this.onListScroll()},o.map((d,g)=>this.row(d,g)),a?en({class:"picker-empty"},this.err?`Couldn't load models: ${this.err}`:"No OpenRouter models in the catalog right now."):null),this.err&&!a?en({class:"model-err"},`\u2717 ${this.err}`):null,this.hasKey&&this.models.length?this.filterBox(this.models.length,"model"):null)}row(o,a){let d=()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},g=["picker-row",a===this.highlighted?"active":""];if(o.kind==="unlock")return en({class:g,onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},"+ Add OpenRouter key to unlock models\u2026")));if(o.kind==="default")return en({class:[...g,o.active?"current":"","model-row","model-default-row"],title:"Your normal claude (subscription / API) \u2014 clears the override",onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},"Anthropic (native)"),en({class:"model-trailing"},o.active?this.activeBadge():null)));let m=o.id;return en({class:[...g,o.active?"current":"","model-row"],title:m,onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},o.label),en({class:"model-trailing"},o.active?this.activeBadge():null,this.statusButton(m))))}activeBadge(){return Ji({class:["model-btn","model-active"],title:"Active \u2014 bare claude routes here now"},"active")}statusButton(o){if(this.probing===o)return Ji({class:["model-btn","model-status","probing"]},"probing\u2026");let a=this.probes[o];if(!a)return qc({class:["model-btn","model-status","probe"],title:"Check if it\u2019s callable and which provider caches \u2014 pins the caching one.",onClick:g=>{g.stopPropagation(),this.probe(o)}},"probe");let d=this.badge(a);return qc({class:["model-btn","model-status",d.cls],title:`${d.title} \xB7 click for details`,onClick:g=>{g.stopPropagation(),this.showDiag(o)}},d.text)}badge(o){if(!o.ok||o.callable===!1)return{text:"error",cls:"bad",title:o.error||"unavailable"};let a=o.provider?` on ${o.provider}`:"",d=o.cache?.works,g=ASt(d);return d===!0?{text:"cached",cls:g,title:`caching confirmed${a} \u2014 ${o.cache?.note||""}`}:d===!1?{text:"uncached",cls:g,title:`no caching${a} \u2014 ${o.cache?.note||""}`}:{text:"cache?",cls:g,title:`${o.cache?.note||"caching unconfirmed"}${a}`}}diagView(o){return en({class:"picker model-picker diag-mode",tabIndex:0,onMounted:a=>a.focus(),onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDiag())}},en({class:"diag-head"},Ji({class:"diag-name"},this.label(o)),en({class:"diag-head-acts"},qc({class:"diag-back",title:"Re-run the probe",disabled:this.probing===o,onClick:a=>{a.stopPropagation(),this.probe(o)}},this.probing===o?"probing\u2026":"probe again"),qc({class:"diag-back",title:"Back to the model list",onClick:a=>{a.stopPropagation(),this.closeDiag()}},"\u2190 models"))),en({class:"diag-body"},...this.diagLines(o)))}diagLines(o){let a=this.probes[o];if(!a)return[en({class:["diag-line","muted"]},"Not probed yet \u2014 close this and hit probe.")];let d=[];if(!a.ok||a.callable===!1)d.push(en({class:["diag-line","bad"]},`\u2717 Not callable${a.status?` (HTTP ${a.status})`:""}: ${a.error||"unknown error"}`)),a.restriction&&d.push(en({class:["diag-line","warn"]},`\u26A0 ${a.restriction}`));else{d.push(en({class:["diag-line","ok"]},`\u2713 Callable${a.ms?` \xB7 ${a.ms}ms`:""}${a.sample?` \xB7 replied \u201C${a.sample}\u201D`:""}`)),a.provider&&d.push(en({class:["diag-line","muted"]},`Served by ${a.provider} this probe \u2014 the proxy will pin CC's turns to it when caching is confirmed.`));let g=a.cache;if(g){let m=ASt(g.works),v=g.works===!0?"\u2713 Caching works":g.works===!1?"\u2717 No caching":"~ Caching unconfirmed",w=a.provider?` on ${a.provider}`:"";d.push(en({class:["diag-line",m]},`${v}${w} \u2014 ${g.note}`)),g.works!==!0&&d.push(en({class:["diag-line","muted"]},"Without prompt caching every turn re-bills the whole context \u2014 costly over a long session."))}}return d.push(en({class:["diag-line","muted","small"]},"Caching on OpenRouter is per-provider; the proxy pins the provider a probe confirms so CC keeps caching. A probe makes two small test calls.")),d}keyView(){return en({class:"picker model-picker key-entry",tabIndex:0,onKeyDown:o=>{o.key==="Escape"&&(o.stopPropagation(),this.cancelKeyEntry())}},en({class:"key-entry-head"},"Paste your OpenRouter API key"),Hee({target:this,prop:()=>this.keyDraft,id:"or-key-input",attrs:{class:"bulb-filter",placeholder:"sk-or-\u2026",ariaLabel:"OpenRouter API key",onKeyDown:o=>{o.key==="Enter"?(o.preventDefault(),this.saveKey()):o.key==="Escape"&&(o.stopPropagation(),this.cancelKeyEntry())}}}),this.err?en({class:"model-err"},`\u2717 ${this.err}`):null,en({class:"key-entry-acts"},qc({class:"pill",onClick:o=>{o.stopPropagation(),this.cancelKeyEntry()}},"Cancel"),qc({class:["pill","on"],onClick:o=>{o.stopPropagation(),this.saveKey()}},this.busy?"Saving\u2026":"Save")),en({class:"key-entry-note"},"Written to .env in this project (gitignored). Used only via OpenRouter."))}};document.title="Claude Mirror";var Gxe=new Xre;new e6t({root:new Wre({title:"Claude Mirror",pills:[Gxe],overlays:[()=>Gxe.watchdogView()],onPollTick:()=>{Gxe.tickState()}}),id:"app"});
|
|
1382
|
+
`);this.busy=T;let D=m!==this.latestModel;this.latestModel=m??null;let P=this.composer&&v?this.composer.syncFromPoll(v):!1;(a.length||I||D||P||L)&&this.update(),(a.length||P)&&this.messageList.scrollSoon(),this.#s?.()}catch(a){console.error("[mirror] poll failed",a)}setTimeout(o,600)};o()}apply(o){switch(o.type){case"cleared":this.messageList.clear(),this.tokens={in:0,out:0,cached:0,cacheCreate:0},this.cost=0;break;case"session":this.sessionId=o.sessionId,this.updateTitle();break;case"user":this.messageList.applyUser(o);break;case"assistant":this.messageList.applyAssistant(o);break;case"tool_result":this.messageList.applyToolResult(o);break;case"fork":this.messageList.applyFork(o);break;case"usage":this.tokens={in:o.in,out:o.out,cached:o.cached,cacheCreate:o.cacheCreate},this.cost+=o.cost??0;break}}view(){return en({class:"app"},en({class:"chat"},this.messageList.view(),...this.#r.map(o=>o()),this.statusbar()),this.composer?.enabled?this.composer.view():null)}statusbar(){return en({class:"statusbar"},en({class:"statusbar-actions"},this.prosePill.view(),...this.pills.map(o=>o.view()),this.tokenPill.view(),this.sessionPicker.view(),this.bulbsPill.view()))}};var yvn=[[0,"Low"],[1,"Med"],[2,"High"]],kvn=1,Yre=s=>s?.message??String(s),xvn=()=>o6t({viewBox:"0 0 24 24",width:"15",height:"15",class:"anthropic-glyph",fill:"currentColor"},s6t({d:"M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z"})),ASt=s=>s===!0?"ok":s===!1?"bad":"warn",Xre=class extends S7{models=[];hasKey=!0;loaded=!1;current={active:!1,managed:!1,model:null,port:null,provider:null,routedModel:null,caching:"unknown",reasoning:null,externalBaseUrl:null};busy=!1;err=null;enteringKey=!1;keyDraft="";probes={};probing=null;openDiag=null;infoOpen=!1;ticking=!1;keepOpenSelector=".model-wrap";filterId="model-filter";listSelector="#model-list";filterNoun="model";search(){return Promise.resolve([])}modeToggle(){return null}onActivate(o){let a=this.rows()[o];a&&(a.kind==="default"?this.clear():a.kind==="unlock"?this.beginKeyEntry():this.set(a.id))}onAttached(){this.refresh()}async refresh(){try{let[o,a]=await Promise.all([tb.server.listSwitchModels(),tb.server.switchState()]);this.models=o.models,this.hasKey=o.hasKey,this.current=a,this.err=o.error??null}catch(o){this.err=Yre(o),console.error("[mirror] switcher refresh failed",o)}finally{this.loaded=!0,this.update()}}async tickState(){if(!(this.ticking||this.enteringKey)){this.ticking=!0;try{let o=await tb.server.switchState(),a=o.active!==this.current.active||o.model!==this.current.model||o.caching!==this.current.caching||o.routedModel!==this.current.routedModel||o.externalBaseUrl!==this.current.externalBaseUrl||o.provider!==this.current.provider||o.reasoning!==this.current.reasoning;this.current=o,a&&this.update()}catch{}finally{this.ticking=!1}}}rows(){let o=[];if(!this.hasKey)o.push({kind:"unlock"});else{let a=this.filter.trim().toLowerCase(),d=null;for(let g of this.models){if(a&&!g.label.toLowerCase().includes(a)&&!g.id.toLowerCase().includes(a))continue;let m={kind:"model",id:g.id,label:g.label,active:this.current.active&&this.current.model===g.id};m.active?d=m:o.push(m)}d&&o.push(d)}return o.push({kind:"default",active:!this.current.active&&!this.current.externalBaseUrl}),o}activeIndex(){let o=this.rows(),a=o.findIndex(d=>d.active);return a<0?Math.max(0,o.length-1):a}async show(){this.beginOpen(),this.refreshList(this.activeIndex()),this.focusFilter(),await this.refresh(),this.refreshList(this.activeIndex()),this.armClose()}onClosed(){super.onClosed(),this.enteringKey=!1,this.keyDraft="",this.openDiag=null,this.infoOpen=!1,this.err=null}async probe(o){if(!this.probing){this.probing=o,this.update();try{this.probes[o]=await tb.server.probeModel({model:o})}catch(a){this.probes[o]={ok:!1,error:Yre(a)}}this.probing=null,this.update()}}showDiag(o){this.openDiag=o,this.update()}closeDiag(){this.openDiag=null,this.update(),this.focusFilter()}label(o){return o?this.models.find(a=>a.id===o)?.label||o.split("/").pop()||o:"Anthropic"}async runBusy(o,a){this.busy=!0,this.err=null,this.update();try{let d=await o();if(d?.ok===!1)return this.err=d.error||a,this.busy=!1,this.update(),!1}catch(d){return this.err=Yre(d),this.busy=!1,this.update(),!1}return this.busy=!1,!0}async set(o){await this.runBusy(()=>tb.server.setSwitchModel({model:o}),"failed to set model")&&(await this.refresh(),this.close())}async clear(){await this.runBusy(()=>tb.server.clearSwitchModel(),"failed to revert")&&(await this.refresh(),this.close())}get reasoningSel(){return this.current.reasoning??kvn}set reasoningSel(o){this.setReasoning(o)}async setReasoning(o){if(this.current.reasoning!==o){this.current={...this.current,reasoning:o},this.update();try{let a=await tb.server.setReasoning({level:o});a?.ok===!1&&(this.err=a.error||"failed to set reasoning",this.update())}catch(a){this.err=Yre(a),this.update()}}}beginKeyEntry(){this.enteringKey=!0,this.keyDraft="",this.update(),setTimeout(()=>document.getElementById("or-key-input")?.focus())}cancelKeyEntry(){this.enteringKey=!1,this.keyDraft="",this.update(),this.focusFilter()}async saveKey(){let o=this.keyDraft.trim();o&&await this.runBusy(()=>tb.server.saveOpenRouterKey({key:o}),"failed to save key")&&(this.enteringKey=!1,this.keyDraft="",await this.refresh(),this.refreshList(this.activeIndex()))}get overridden(){return this.current.active}get uncached(){return this.current.active&&this.current.caching==="uncached"}watchdogView(){return this.uncached?en({class:["model-banner","warn"]},Ji({class:"model-banner-text"},`${this.label(this.current.model)} was served uncached via OpenRouter \u2014 the full context is re-billed each turn. Probe the model to pin a provider that caches, or pick a different one.`)):null}head(){return this.current.active?en({class:"model-head"},qc({class:"model-info-toggle",onClick:o=>{o.stopPropagation(),this.infoOpen=!0,this.update()}},"Routing info"),en({class:"reasoning-ctl",title:"Reasoning sets the route\u2019s base thinking effort."},Ji({class:"reasoning-label"},"reasoning"),this.reasoningSelect())):this.current.externalBaseUrl?en({class:"model-head"},Ji({class:["model-route","warn"]},"Custom base URL set elsewhere \u2014 \u201CAnthropic (native)\u201D clears it")):null}reasoningSelect(){return i6t({target:this,prop:()=>this.reasoningSel,attrs:{class:"reasoning-select",onClick:o=>o.stopPropagation()},options:yvn.map(([o,a])=>({value:o,label:a}))})}infoView(){let o=this.label(this.current.model),a=()=>{this.infoOpen=!1,this.update()};return en({class:"picker model-picker diag-mode",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&(d.stopPropagation(),a())}},en({class:"diag-head"},Ji({class:"diag-name"},"Routing"),en({class:"diag-head-acts"},qc({class:"diag-back",title:"Back to the model list",onClick:d=>{d.stopPropagation(),a()}},"\u2190 models"))),en({class:"diag-body"},en({class:"diag-line"},`You are currently routing to ${o} via OpenRouter, not your Anthropic subscription.`),en({class:"diag-line"},"The route is shared by every Claude Code conversation scoped to this project."),en({class:"diag-line"},"Switching to or from Anthropic toggles the proxy, so for existing conversations you\u2019ll need to:"),en({class:["diag-line","diag-bullet"]},"\u2022 Relaunch the Claude CLI"),en({class:["diag-line","diag-bullet"]},"\u2022 or, in the VS Code extension, run \u201CDeveloper: Restart Extension Host\u201D (Cmd/Ctrl+Shift+P).")))}view(){let o=this.current.active,a=this.uncached,d=!o&&!!this.current.externalBaseUrl,g=this.label(this.current.model),m=a?`${g} via OpenRouter, uncached \u2014 full context re-billed each turn. Click to switch or revert.`:o?`claude \u2192 ${this.current.model}: its Anthropic API is proxied to OpenRouter. Click to switch or revert.`:d?`Custom ANTHROPIC_BASE_URL set outside this tool (${this.current.externalBaseUrl}). Click to manage.`:"Anthropic (native) \u2014 click to proxy claude\u2019s Anthropic API to an OpenRouter model.",v=o?g:d?"custom route":xvn();return en({class:"model-wrap"},qc({class:["pill",o||d?"on":"glyph",a?"warn":""],title:m,ariaLabel:o||d?void 0:"Anthropic (native)",onClick:w=>{w.stopPropagation(),this.open?this.close():this.show()}},v),this.open?this.popup():null)}popup(){if(this.enteringKey)return this.keyView();if(this.infoOpen)return this.infoView();if(this.openDiag)return this.diagView(this.openDiag);let o=this.rows(),a=this.loaded&&this.hasKey&&!this.models.length;return en({class:"picker model-picker"},this.head(),en({id:"model-list",class:"picker-list",onScroll:()=>this.onListScroll()},o.map((d,g)=>this.row(d,g)),a?en({class:"picker-empty"},this.err?`Couldn't load models: ${this.err}`:"No OpenRouter models in the catalog right now."):null),this.err&&!a?en({class:"model-err"},`\u2717 ${this.err}`):null,this.hasKey&&this.models.length?this.filterBox(this.models.length,"model"):null)}row(o,a){let d=()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},g=["picker-row",a===this.highlighted?"active":""];if(o.kind==="unlock")return en({class:g,onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},"+ Add OpenRouter key to unlock models\u2026")));if(o.kind==="default")return en({class:[...g,o.active?"current":"","model-row","model-default-row"],title:"Your normal claude (subscription / API) \u2014 clears the override",onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},"Anthropic (native)"),en({class:"model-trailing"},o.active?this.activeBadge():null)));let m=o.id;return en({class:[...g,o.active?"current":"","model-row"],title:m,onMouseEnter:d,onClick:()=>this.onActivate(a)},en({class:"picker-row-main"},Ji({class:"picker-dot"}),Ji({class:"picker-preview"},o.label),en({class:"model-trailing"},o.active?this.activeBadge():null,this.statusButton(m))))}activeBadge(){return Ji({class:["model-btn","model-active"],title:"Active \u2014 bare claude routes here now"},"active")}statusButton(o){if(this.probing===o)return Ji({class:["model-btn","model-status","probing"]},"probing\u2026");let a=this.probes[o];if(!a)return qc({class:["model-btn","model-status","probe"],title:"Check if it\u2019s callable and which provider caches \u2014 pins the caching one.",onClick:g=>{g.stopPropagation(),this.probe(o)}},"probe");let d=this.badge(a);return qc({class:["model-btn","model-status",d.cls],title:`${d.title} \xB7 click for details`,onClick:g=>{g.stopPropagation(),this.showDiag(o)}},d.text)}badge(o){if(!o.ok||o.callable===!1)return{text:"error",cls:"bad",title:o.error||"unavailable"};let a=o.provider?` on ${o.provider}`:"",d=o.cache?.works,g=ASt(d);return d===!0?{text:"cached",cls:g,title:`caching confirmed${a} \u2014 ${o.cache?.note||""}`}:d===!1?{text:"uncached",cls:g,title:`no caching${a} \u2014 ${o.cache?.note||""}`}:{text:"cache?",cls:g,title:`${o.cache?.note||"caching unconfirmed"}${a}`}}diagView(o){return en({class:"picker model-picker diag-mode",tabIndex:0,onMounted:a=>a.focus(),onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDiag())}},en({class:"diag-head"},Ji({class:"diag-name"},this.label(o)),en({class:"diag-head-acts"},qc({class:"diag-back",title:"Re-run the probe",disabled:this.probing===o,onClick:a=>{a.stopPropagation(),this.probe(o)}},this.probing===o?"probing\u2026":"probe again"),qc({class:"diag-back",title:"Back to the model list",onClick:a=>{a.stopPropagation(),this.closeDiag()}},"\u2190 models"))),en({class:"diag-body"},...this.diagLines(o)))}diagLines(o){let a=this.probes[o];if(!a)return[en({class:["diag-line","muted"]},"Not probed yet \u2014 close this and hit probe.")];let d=[];if(!a.ok||a.callable===!1)d.push(en({class:["diag-line","bad"]},`\u2717 Not callable${a.status?` (HTTP ${a.status})`:""}: ${a.error||"unknown error"}`)),a.restriction&&d.push(en({class:["diag-line","warn"]},`\u26A0 ${a.restriction}`));else{d.push(en({class:["diag-line","ok"]},`\u2713 Callable${a.ms?` \xB7 ${a.ms}ms`:""}${a.sample?` \xB7 replied \u201C${a.sample}\u201D`:""}`)),a.provider&&d.push(en({class:["diag-line","muted"]},`Served by ${a.provider} this probe \u2014 the proxy will pin CC's turns to it when caching is confirmed.`));let g=a.cache;if(g){let m=ASt(g.works),v=g.works===!0?"\u2713 Caching works":g.works===!1?"\u2717 No caching":"~ Caching unconfirmed",w=a.provider?` on ${a.provider}`:"";d.push(en({class:["diag-line",m]},`${v}${w} \u2014 ${g.note}`)),g.works!==!0&&d.push(en({class:["diag-line","muted"]},"Without prompt caching every turn re-bills the whole context \u2014 costly over a long session."))}}return d.push(en({class:["diag-line","muted","small"]},"Caching on OpenRouter is per-provider; the proxy pins the provider a probe confirms so CC keeps caching. A probe makes two small test calls.")),d}keyView(){return en({class:"picker model-picker key-entry",tabIndex:0,onKeyDown:o=>{o.key==="Escape"&&(o.stopPropagation(),this.cancelKeyEntry())}},en({class:"key-entry-head"},"Paste your OpenRouter API key"),Hee({target:this,prop:()=>this.keyDraft,id:"or-key-input",attrs:{class:"bulb-filter",placeholder:"sk-or-\u2026",ariaLabel:"OpenRouter API key",onKeyDown:o=>{o.key==="Enter"?(o.preventDefault(),this.saveKey()):o.key==="Escape"&&(o.stopPropagation(),this.cancelKeyEntry())}}}),this.err?en({class:"model-err"},`\u2717 ${this.err}`):null,en({class:"key-entry-acts"},qc({class:"pill",onClick:o=>{o.stopPropagation(),this.cancelKeyEntry()}},"Cancel"),qc({class:["pill","on"],onClick:o=>{o.stopPropagation(),this.saveKey()}},this.busy?"Saving\u2026":"Save")),en({class:"key-entry-note"},"Written to .env in this project (gitignored). Used only via OpenRouter."))}};document.title="Claude Mirror";var Gxe=new Xre;new e6t({root:new Wre({title:"Claude Mirror",pills:[Gxe],overlays:[()=>Gxe.watchdogView()],onPollTick:()=>{Gxe.tickState()}}),id:"app"});
|
|
1383
1383
|
/*! Bundled license information:
|
|
1384
1384
|
|
|
1385
1385
|
dompurify/dist/purify.es.mjs:
|
|
@@ -2217,7 +2217,7 @@ var Patcher = class _Patcher {
|
|
|
2217
2217
|
|
|
2218
2218
|
// cli/agents/pi/server/piPatcherExtension.ts
|
|
2219
2219
|
var DESCRIPTION = true ? "Apply unified diffs to files \u2014 tolerant of form, strict about intent. Repairs sloppy AI-generated diffs (mangled headers, whitespace drift, missing prefixes; line numbers can be wrong or absent \u2014 hunks anchor by fuzzy-matched context lines) and applies all hunks atomically when the intent is unambiguous; fails with a precise, typed error when it isn't. Use for multi-hunk edits in one step, or when exact string-replacement editing fails on whitespace or invisible characters." : "Apply unified diffs to files.";
|
|
2220
|
-
var BUILD_TAG = true ? "matchu-patchu-pi 0.2.0, built 2026-07-09 17:
|
|
2220
|
+
var BUILD_TAG = true ? "matchu-patchu-pi 0.2.0, built 2026-07-09 18:17:19" : "matchu-patchu-pi dev";
|
|
2221
2221
|
var errorBlocks = (errors) => {
|
|
2222
2222
|
const parts = [`Patch failed with ${errors.length} error(s):`];
|
|
2223
2223
|
for (const e of errors) parts.push("", e.toString());
|