@coseung2/opencodex 2.8.0-cs.4 → 2.8.0-cs.6
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/bin/ocx-notch.mjs +4 -0
- package/gui/dist/assets/{index-CKr637sN.js → index-pD7leCGr.js} +1 -1
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/packages/ocx-notch/README.md +3 -1
- package/src/cli/index.ts +67 -29
- package/src/config.ts +4 -3
- package/src/providers/registry.ts +1 -0
- package/src/server/lifecycle.ts +23 -0
- package/src/server/memory-watchdog.ts +72 -7
- package/src/server/proxy-liveness.ts +5 -1
- package/vendor/ocx-notch/win32-x64/ocx-notch.exe +0 -0
package/bin/ocx-notch.mjs
CHANGED
|
@@ -64,4 +64,4 @@ v2: spawn_agent を備えたマルチスレッドエージェント。すべて
|
|
|
64
64
|
"max_tokens": 64,
|
|
65
65
|
"messages": [{"role": "user", "content": ${r}}]
|
|
66
66
|
}'`;return(0,z.jsxs)(`section`,{className:`panel api-panel awi-usage-panel`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:n(`api.workspace.usageExamples`)}),(0,z.jsxs)(`div`,{className:`awi-usage-panel-body`,children:[(0,z.jsxs)(`div`,{className:`awi-usage-example`,children:[(0,z.jsx)(`h4`,{className:`awi-usage-example-title`,children:n(`api.usageChatTitle`)}),(0,z.jsx)(Nu,{text:i})]}),(0,z.jsxs)(`div`,{className:`awi-usage-example`,children:[(0,z.jsx)(`h4`,{className:`awi-usage-example-title`,children:n(`api.usageResponsesTitle`)}),(0,z.jsx)(Nu,{text:a})]}),t&&(0,z.jsxs)(`div`,{className:`awi-usage-example`,children:[(0,z.jsx)(`h4`,{className:`awi-usage-example-title`,children:n(`api.usageMessagesTitle`)}),(0,z.jsx)(Nu,{text:o})]})]})]})}var zu=[`opencode`,`pi`],Bu={opencode:`api.clientConfig.clientOpencode`,pi:`api.clientConfig.clientPi`},Vu={opencode:`/provider-icons/opencode.svg`,pi:`/provider-icons/pi.svg`};function Hu({client:e,apiBase:t,onOpenDetails:n,onCopy:r,onDownload:i}){let a=K(),[o,s]=(0,_.useState)(0),c=[t,e,String(o)].join(`|`),[l,u]=(0,_.useState)(null);(0,_.useEffect)(()=>{let n=new AbortController,r=!1;return(async()=>{try{let i=await fetch(`${t}/api/client-config?client=${encodeURIComponent(e)}`,{signal:n.signal});if(!i.ok)throw Error(String(i.status));let a=await i.json();if(r)return;u({key:c,data:a,failed:!1})}catch{if(r)return;u({key:c,data:null,failed:!0})}})(),()=>{r=!0,n.abort()}},[t,e,c]);let d=l!==null&&l.key===c?l:null,f=d?.data??null,p=d?.failed??!1,m=d===null,h=a(Bu[e]),g=Vu[e],v=f?`${JSON.stringify(f.config,null,2)}\n`:``,y=(0,_.useCallback)(t=>{f&&n(e,f,v,t.currentTarget)},[e,f,v,n]);return(0,z.jsxs)(`li`,{className:`awi-clientconfig-row`,children:[(0,z.jsx)(`span`,{className:`awi-clientconfig-mark`,"aria-hidden":`true`,children:g?(0,z.jsx)(`img`,{src:g,alt:``,width:20,height:20}):(0,z.jsx)(`span`,{className:`awi-clientconfig-monogram`,children:h.slice(0,1)})}),(0,z.jsxs)(`span`,{className:`awi-clientconfig-identity`,children:[(0,z.jsx)(`span`,{className:`awi-clientconfig-name`,children:h}),(0,z.jsx)(`span`,{className:`muted text-label awi-clientconfig-meta`,children:m?a(`api.clientConfig.loading`):p||!f?(0,z.jsx)(`span`,{role:`alert`,children:a(`api.clientConfig.rowError`,{client:h})}):a(`api.clientConfig.rowMeta`,{destination:f.destination,count:f.modelCount})})]}),(0,z.jsx)(`span`,{className:`awi-clientconfig-row-actions`,children:p&&!m?(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>s(e=>e+1),children:a(`common.retry`)}):(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":a(`api.clientConfig.copyAria`,{client:h}),disabled:!f,onClick:()=>{f&&r(e,v)},children:a(`api.clientConfig.copy`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-sm`,"aria-label":a(`api.clientConfig.downloadAria`,{client:h}),disabled:!f,onClick:()=>{f&&i(e,f,v)},children:a(`api.clientConfig.download`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,"aria-label":a(`api.clientConfig.detailsAria`,{client:h}),disabled:!f,onClick:y,children:a(`api.clientConfig.details`)})]})})]})}function Uu({client:e,envelope:t,json:n,hasKeys:r,onClose:i,onCopy:a,onDownload:o}){let s=K(),c=(0,_.useRef)(null),l=`awi-clientconfig-dialog-${e}`;return(0,_.useEffect)(()=>{let e=c.current;return e&&!e.open&&e.showModal(),()=>{e?.open&&e.close()}},[]),(0,z.jsxs)(`dialog`,{ref:c,className:`modal-overlay`,"aria-labelledby":l,onCancel:(0,_.useCallback)(e=>{e.preventDefault(),i()},[i]),children:[(0,z.jsx)(`button`,{type:`button`,className:`modal-backdrop-dismiss`,"aria-label":s(`common.close`),tabIndex:-1,onClick:i}),(0,z.jsxs)(`div`,{className:`modal-card awi-clientconfig-dialog`,onClick:e=>e.stopPropagation(),role:`document`,children:[(0,z.jsxs)(`div`,{className:`modal-head`,children:[(0,z.jsx)(`h3`,{id:l,children:s(Bu[e])}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:i,children:s(`common.close`)})]}),(0,z.jsx)(`pre`,{className:`api-code api-example-pre awi-clientconfig-json`,tabIndex:0,role:`group`,"aria-label":s(`api.clientConfig.jsonLabel`,{client:s(Bu[e])}),children:n}),(0,z.jsx)(`p`,{className:`muted small awi-clientconfig-count`,children:s(`api.clientConfig.modelCount`,{count:t.modelCount})}),t.modelsWithoutLimits>0&&(0,z.jsx)(`p`,{className:`muted small awi-clientconfig-degraded`,children:s(`api.clientConfig.missingLimits`,{count:t.modelsWithoutLimits,total:t.modelCount})}),!r&&(0,z.jsx)(`p`,{className:`muted small awi-clientconfig-nokey`,children:s(`api.clientConfig.noKeyYet`,{env:t.apiKeyEnv})}),(0,z.jsxs)(`div`,{className:`awi-clientconfig-line`,children:[(0,z.jsx)(`span`,{className:`muted text-label`,children:s(`api.clientConfig.destination`)}),(0,z.jsx)(Nu,{text:t.destination})]}),(0,z.jsxs)(`div`,{className:`awi-clientconfig-line`,children:[(0,z.jsx)(`span`,{className:`muted text-label`,children:s(`api.clientConfig.envHint`)}),(0,z.jsx)(Nu,{text:t.exportHint})]}),(0,z.jsx)(`p`,{className:`muted small awi-clientconfig-merge`,children:s(`api.clientConfig.mergeWarning`)}),(0,z.jsx)(`p`,{className:`muted text-label awi-clientconfig-where-title`,children:s(`api.clientConfig.whereDisclosure`)}),(0,z.jsx)(`p`,{className:`muted small`,children:s(`api.clientConfig.whereBody`)}),(0,z.jsxs)(`div`,{className:`modal-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,onClick:a,children:s(`api.clientConfig.copy`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-sm`,onClick:o,children:s(`api.clientConfig.download`)})]})]})]})}function Wu({apiBase:e,baseUrl:t,hasKeys:n}){let r=K(),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(``),c=(0,_.useRef)(null);(0,_.useEffect)(()=>{if(i!==null)return;let e=c.current;e&&(c.current=null,e.isConnected&&e.focus())},[i]);let l=(0,_.useCallback)(async(e,t,n)=>{try{await navigator.clipboard.writeText(t),s(n?r(`api.clientConfig.copiedAnnounceClient`,{client:r(Bu[e])}):r(`api.clientConfig.copiedAnnounce`))}catch{s(r(`api.clientConfig.copyFailed`))}},[r]),u=(0,_.useCallback)((e,t,n)=>{let i=URL.createObjectURL(new Blob([n],{type:`application/json`})),a=document.createElement(`a`);a.href=i,a.download=t.filename,a.click(),URL.revokeObjectURL(i),s(r(`api.clientConfig.downloadedAnnounce`,{filename:t.filename,destination:t.destination}))},[r]),d=(0,_.useCallback)(()=>a(null),[]),f=(0,_.useCallback)((e,t,n,r)=>{c.current=r,a({client:e,envelope:t,json:n})},[]);return(0,z.jsxs)(`section`,{className:`panel api-panel awi-clientconfig-panel`,children:[(0,z.jsx)(`div`,{className:`api-panel-head awi-clientconfig-head`,children:(0,z.jsx)(`h3`,{className:`panel-title`,children:r(`api.clientConfig.title`)})}),(0,z.jsx)(`ul`,{className:`awi-clientconfig-rows`,"aria-label":r(`api.clientConfig.rowsLabel`),children:zu.map(t=>(0,z.jsx)(Hu,{client:t,apiBase:e,onOpenDetails:f,onCopy:(e,t)=>{l(e,t,!0)},onDownload:u},t))}),(0,z.jsxs)(`div`,{className:`awi-clientconfig-line`,children:[(0,z.jsx)(`span`,{className:`muted text-label`,children:r(`api.baseUrl`)}),(0,z.jsx)(Nu,{text:t})]}),(0,z.jsx)(`div`,{className:`sr-only`,"aria-live":`polite`,"aria-atomic":`true`,children:o}),i&&(0,z.jsx)(Uu,{client:i.client,envelope:i.envelope,json:i.json,hasKeys:n,onClose:d,onCopy:()=>{l(i.client,i.json,!1)},onDownload:()=>u(i.client,i.envelope,i.json)})]})}function Gu({keys:e,keysLoading:t,keysLoadFailed:n,attributionSince:r,localeTag:i,busy:a,onSelect:o}){let s=K();return(0,z.jsxs)(`div`,{className:`panel api-panel awi-keylist-panel`,"aria-busy":t,children:[(0,z.jsx)(`div`,{className:`api-panel-head`,children:(0,z.jsx)(`h3`,{className:`panel-title`,children:t?s(`api.activeKeysLoading`):s(`api.activeKeys`,{count:e.length})})}),t?(0,z.jsx)(`div`,{className:`api-active-keys-skeleton`,role:`status`,"aria-label":s(`common.loading`)}):e.length===0?(0,z.jsx)(`p`,{className:`muted small`,children:s(n?`api.keysLoadFailed`:`api.noKeys`)}):(0,z.jsx)(`div`,{className:`tbl-wrap`,children:(0,z.jsxs)(`table`,{className:`tbl awi-keylist-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:s(`api.colName`)}),(0,z.jsx)(`th`,{children:s(`api.colKey`)}),(0,z.jsx)(`th`,{children:s(`api.attribution.requests7d`)}),(0,z.jsx)(`th`,{children:s(`api.attribution.lastUsed`)})]})}),(0,z.jsx)(`tbody`,{children:e.map(e=>(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`button`,{type:`button`,className:`awi-keylist-name`,disabled:a,onClick:()=>o(e.id),children:e.name})}),(0,z.jsx)(`td`,{children:(0,z.jsx)(`code`,{children:e.prefix})}),(0,z.jsx)(`td`,{children:r?e.usage.ambiguous?s(`api.attribution.railAmbiguous`):e.usage.requests7d.toLocaleString(i):s(`api.attribution.unavailable`)}),(0,z.jsx)(`td`,{children:!r||e.usage.ambiguous?`—`:e.usage.lastUsedAt?Au(e.usage.lastUsedAt,i):s(`api.attribution.neverUsed`)})]},e.id))})]})})]})}function Ku({keys:e,apiBase:t,attributionSince:n,historyTruncated:r,authMatrix:i,keysLoading:a,keysLoadFailed:o,endpoints:s,claudeCodeEnabled:c,localeTag:l,newName:u,creating:d,newKey:f,copied:p,filteredModels:m,modelsLoading:h,modelsRefreshing:g=!1,modelsLoadFailed:v,modelCount:y,hasModelData:b,modelQuery:x,copiedModelId:S,modelTests:C,canTestModels:w,onNewNameChange:T,onCreate:E,onDismissNewKey:D,onCopyKey:O,onDelete:k,onRename:A,onModelQueryChange:j,onCopyModelId:M,onTestModel:N,onRetryModels:P,sourceLabel:F,protocolLabel:I}){let L=K(),[R,B]=(0,_.useState)(null),[V,H]=(0,_.useState)(!1),[U,W]=(0,_.useState)(!1),[ee,te]=(0,_.useState)(!1),[ne,re]=(0,_.useState)(!1),[G,ie]=(0,_.useState)(``),[ae,oe]=(0,_.useState)(!1),[se,ce]=(0,_.useState)(!1),[le,de]=(0,_.useState)(!1),fe=R?e.find(e=>e.id===R)??null:null,pe=ee||ae,me=(0,_.useMemo)(()=>[{id:`keys`,label:L(`api.section.keys`),meta:a?void 0:String(e.length)},{id:`connect`,label:L(`api.section.connect`)},{id:`endpoints`,label:L(`api.section.endpoints`)},{id:`models`,label:L(`api.section.models`),meta:String(y)},{id:`examples`,label:L(`api.section.examples`)}],[L,e.length,a,y]),he=()=>{H(!1),W(!1)},ge=()=>{B(null),he(),re(!1),ce(!1),de(!1)};(0,_.useEffect)(()=>{if(!V)return;let e=window.setTimeout(()=>W(!0),300);return()=>window.clearTimeout(e)},[V]);let ve=()=>{fe&&H(!0)},ye=async()=>{if(!(!fe||!U||ee)){te(!0),de(!1);try{await k(fe.id)?(he(),B(null)):de(!0)}finally{te(!1)}}},be=()=>{fe&&(ie(fe.name),ce(!1),re(!0))},xe=async()=>{if(!fe||ae)return;let e=G.trim();if(!e||e===fe.name){re(!1);return}oe(!0),ce(!1);try{await A(fe.id,e)?re(!1):ce(!0)}finally{oe(!1)}};return(0,z.jsxs)(`div`,{className:`apikeys-workspace-shell`,children:[!fe&&(0,z.jsx)(lc,{scope:`api`,items:me,ariaLabel:L(`api.workspace.sections`)}),(0,z.jsx)(`div`,{className:`apikeys-workspace-root`,children:(0,z.jsx)(`section`,{className:`apikeys-workspace-main`,"aria-label":L(`api.workspace.details`),children:fe?(0,z.jsxs)(`div`,{className:`awi-detail`,children:[(0,z.jsx)(`div`,{className:`awi-detail-toolbar`,children:(0,z.jsxs)(`button`,{type:`button`,className:`awi-back`,onClick:ge,disabled:pe,children:[(0,z.jsx)(_e,{className:`awi-back-chevron`,"aria-hidden":`true`}),L(`modal.back`)]})}),(0,z.jsxs)(`div`,{className:`awi-detail-body`,children:[(0,z.jsxs)(`div`,{className:`awi-detail-head`,children:[(0,z.jsx)(`h2`,{className:`awi-detail-title`,children:fe.name}),(0,z.jsx)(`span`,{className:`awi-detail-actions`,children:V?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-danger btn-sm awi-confirm-delete`,onClick:()=>{ye()},disabled:!U||ee,children:[(0,z.jsx)(ue,{}),` `,L(ee?`api.key.deleting`:`api.confirm`)]},`confirm-delete`),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:he,disabled:ee,children:L(`common.cancel`)})]}):(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:be,disabled:ne,children:L(`api.key.rename`)},`rename`),(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-danger btn-sm`,onClick:ve,"aria-label":L(`api.deleteAria`),children:[(0,z.jsx)(ue,{}),` `,L(`api.workspace.deleteKey`)]},`request-delete`)]})})]}),V&&(0,z.jsx)(`p`,{className:`muted awi-delete-hint`,children:L(`api.workspace.deleteConfirm`)}),le&&(0,z.jsx)(`p`,{className:`awi-delete-error`,role:`alert`,children:L(`api.deleteFailed`)}),ne&&(0,z.jsxs)(`div`,{className:`awi-rename`,children:[(0,z.jsx)(`label`,{className:`awi-rename-label`,htmlFor:`awi-key-name`,children:L(`api.key.name`)}),(0,z.jsx)(`input`,{id:`awi-key-name`,className:`input`,type:`text`,value:G,maxLength:64,disabled:ae,onChange:e=>ie(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),xe())}}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-sm`,onClick:()=>{xe()},disabled:ae,children:L(ae?`api.key.renaming`:`api.key.saveName`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>re(!1),disabled:ae,children:L(`common.cancel`)}),se&&(0,z.jsx)(`p`,{className:`awi-rename-error`,role:`alert`,children:L(`api.key.renameFailed`)})]}),(0,z.jsxs)(`div`,{className:`awi-section`,children:[(0,z.jsx)(`h3`,{className:`awi-section-title`,children:L(`api.workspace.keyDetails`)}),(0,z.jsxs)(`dl`,{className:`awi-kv`,children:[(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(`api.workspace.keyPrefix`)}),(0,z.jsx)(`dd`,{children:(0,z.jsx)(`code`,{children:fe.prefix})})]}),(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(`api.colCreated`)}),(0,z.jsx)(`dd`,{children:Au(fe.createdAt,l)})]})]})]}),(0,z.jsxs)(`div`,{className:`awi-section`,children:[(0,z.jsx)(`h3`,{className:`awi-section-title`,children:L(`api.attribution.title`)}),n?fe.usage.ambiguous?(0,z.jsx)(`p`,{className:`muted`,children:L(`api.attribution.ambiguous`)}):(0,z.jsxs)(`dl`,{className:`awi-kv`,children:[(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(`api.attribution.requests7d`)}),(0,z.jsx)(`dd`,{children:fe.usage.requests7d.toLocaleString(l)})]}),(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(r?`api.attribution.totalRequestsAvailable`:`api.attribution.totalRequests`)}),(0,z.jsx)(`dd`,{children:fe.usage.totalRequests.toLocaleString(l)})]}),(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(`api.attribution.lastUsed`)}),(0,z.jsx)(`dd`,{children:fe.usage.lastUsedAt?Au(fe.usage.lastUsedAt,l):L(`api.attribution.neverUsed`)})]}),(0,z.jsxs)(`div`,{className:`awi-kv-row`,children:[(0,z.jsx)(`dt`,{children:L(r?`api.attribution.sinceAvailable`:`api.attribution.since`)}),(0,z.jsx)(`dd`,{children:Au(n,l)})]})]}):(0,z.jsx)(`p`,{className:`muted`,children:L(`api.attribution.unavailableDetail`)})]})]})]}):(0,z.jsx)(`div`,{className:`awi-overview`,children:(0,z.jsxs)(`div`,{className:`awi-overview-section`,children:[(0,z.jsxs)(`div`,{id:oc(`api`,`keys`),className:`awi-section-anchor`,children:[(0,z.jsx)(Iu,{keys:e,keysLoading:a,keysLoadFailed:o,newName:u,creating:d,newKey:f,copied:p,confirmDelete:null,localeTag:l,showKeyList:!1,onNewNameChange:T,onCreate:E,onDismissNewKey:D,onCopyKey:O,onConfirmDelete:()=>{},onCancelDelete:()=>{},onDelete:()=>{}}),(0,z.jsx)(Gu,{keys:e,keysLoading:a,keysLoadFailed:o,attributionSince:n,localeTag:l,busy:pe,onSelect:e=>{B(e),he(),re(!1),ce(!1),de(!1)}})]}),(0,z.jsx)(`div`,{id:oc(`api`,`connect`),className:`awi-section-anchor`,children:(0,z.jsx)(Wu,{apiBase:t,baseUrl:s.baseUrl,hasKeys:e.length>0})}),(0,z.jsx)(`div`,{id:oc(`api`,`endpoints`),className:`awi-section-anchor`,children:(0,z.jsx)(Fu,{endpoints:s,claudeCodeEnabled:c,authMatrix:i})}),(0,z.jsx)(`div`,{id:oc(`api`,`models`),className:`awi-section-anchor`,children:(0,z.jsx)(Lu,{filteredModels:m,modelsLoading:h,modelsRefreshing:g,modelsLoadFailed:v,modelCount:y,hasModelData:b,modelQuery:x,copiedModelId:S,modelTests:C,claudeCodeEnabled:c,onModelQueryChange:j,onCopyModelId:M,onTestModel:N,onRetryModels:P,canTestModels:w,sourceLabel:F,protocolLabel:I})}),(0,z.jsx)(`div`,{id:oc(`api`,`examples`),className:`awi-section-anchor`,children:(0,z.jsx)(Ru,{endpoints:s,claudeCodeEnabled:c})})]})})})})]})}var qu=[],Ju=15e3;function Yu(e){let t=e.replace(/\/$/,``);if(!t)return Ou;try{return new URL(t).host?ku(`${t}/v1/responses`):Ou}catch{return Ou}}function Xu(e){return!e||!Du(e.authMatrix)||!Array.isArray(e.keys)||e.keys.some(e=>!e||!Tu(e.usage))?null:e}function Zu({apiBase:e}){let{t,locale:n}=Ve(),r=Ie.find(e=>e.code===n)?.htmlLang,i=`ocx.apikeys.list.v2:${e}`,a=`ocx.apikeys.models.v1:${e}`,o=`api-keys:${e}`,s=`api-models:${e}`,c=Xu(Y(i)),l=Y(a),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(``),[m,h]=(0,_.useState)(null),[g,v]=(0,_.useState)({}),[y,b]=(0,_.useState)(``),[x,S]=(0,_.useState)(!1),[C,w]=(0,_.useState)(null),[T,E]=(0,_.useState)(!1),D=(0,_.useRef)(!1),O=(0,_.useCallback)(async n=>{let r=await ut(await fetch(`${e}/api/keys`,{signal:n}));if(!r||!Du(r.authMatrix))throw Error(t(`api.keysLoadFailed`));let a=r.keys??[];if(a.some(e=>!Tu(e.usage)))throw Error(t(`api.keysLoadFailed`));let o=a,s=ku(r.endpoint??``),c={keys:o,endpoints:{baseUrl:r.baseUrl??s.baseUrl,responses:r.responsesEndpoint??r.endpoint??Ou.responses,chatCompletions:r.chatCompletionsEndpoint??s.chatCompletions,messages:r.messagesEndpoint??s.messages,models:r.modelsEndpoint??s.models},claudeCodeEnabled:r.claudeCodeEnabled!==!1,...r.attributionSince?{attributionSince:r.attributionSince}:{},...r.historyTruncated===!0?{historyTruncated:!0}:{},authMatrix:r.authMatrix};return X(i,c),c},[e,i,t]),k=(0,_.useCallback)(async n=>{let r=await fetch(`${e}/v1/models`,{signal:n});if(!r.ok)throw Error(t(`api.modelsLoadFailed`));let i=await r.json(),o=Array.isArray(i)?i:typeof i==`object`&&i&&Array.isArray(i.data)?i.data:null;if(!o)throw Error(t(`api.modelsLoadFailed`));let s=o.filter(e=>typeof e==`object`&&!!e&&typeof e.id==`string`).map(e=>Cu(e)).sort((e,t)=>wu(e).localeCompare(wu(t)));return X(a,s),s},[e,a,t]),A=us(o,[e],O,{isEmpty:e=>e.keys.length===0,initialData:c??void 0}),j=us(s,[e],k,{isEmpty:e=>e.length===0,initialData:l??void 0}),M=A.state,N=j.state,P=M.data??c,F=N.data??l??qu,I=P?.keys??[],L=P?.endpoints??Yu(e),R=P?.claudeCodeEnabled??!0,B=P?.attributionSince,V=P?.historyTruncated===!0,H=P?.authMatrix??[],U=A.refresh,W=j.refresh,ee=(0,_.useMemo)(()=>{let e=f.trim().toLowerCase();return e?F.filter(t=>wu(t).toLowerCase().includes(e)||t.displayName.toLowerCase().includes(e)||t.provider.toLowerCase().includes(e)):F},[f,F]),te=async n=>{if(D.current)return!1;D.current=!0,S(!0),d(null);try{let r=n??y,i=await J(await fetch(`${e}/api/keys`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:r||`default`})}),t(`api.createFailed`));return typeof i?.key!=`string`||i.key.length===0?(d(t(`api.createFailed`)),!1):(w(i.key),b(``),U(),!0)}catch{return d(t(`api.createFailed`)),!1}finally{D.current=!1,S(!1)}},ne=async t=>{d(null);let n=Rt(Ju);try{return(await fetch(`${e}/api/keys`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:t}),signal:n.signal})).ok?(U(),!0):!1}catch{return!1}finally{n.clear()}},re=async(t,n)=>{d(null);let r=Rt(Ju);try{return(await fetch(`${e}/api/keys`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:t,name:n}),signal:r.signal})).ok?(U(),!0):!1}catch{return!1}finally{r.clear()}},G=async()=>{if(C){d(null);try{await navigator.clipboard.writeText(C),E(!0),window.setTimeout(()=>E(!1),2e3)}catch{E(!1),d(t(`api.key.copyFailed`))}}},ie=async e=>{try{await navigator.clipboard.writeText(e),h(e),window.setTimeout(()=>h(t=>t===e?null:t),2e3)}catch{}},ae=e=>e.native?t(`api.sourceNative`):e.provider===`combo`?t(`api.sourceCombo`):e.custom?t(`api.sourceCustom`):e.provider,oe=e=>t(e===`responses`?`api.protocolResponses`:e===`messages`?`api.protocolMessages`:`api.protocolChatCompletions`),se=(e,t)=>e===`responses`?{url:L.responses,body:{model:t,input:`ping`,max_output_tokens:1,stream:!1}}:e===`messages`?{url:L.messages,body:{model:t,max_tokens:1,messages:[{role:`user`,content:`ping`}]}}:{url:L.chatCompletions,body:{model:t,messages:[{role:`user`,content:`ping`}],max_tokens:1,stream:!1}},ce=(e,t,n)=>v(r=>({...r,[e]:{...r[e],[t]:n}})),le=async(e,n)=>{if(!C)return;let r=wu(e),i=se(n,r);ce(r,n,{state:`testing`});try{let e=await fetch(i.url,{method:`POST`,headers:{"Content-Type":`application/json`,"x-opencodex-api-key":C},body:JSON.stringify(i.body)});if(!e.ok){ce(r,n,{state:`error`,detail:(await e.text()).slice(0,160)||String(e.status)});return}ce(r,n,{state:`ok`})}catch(e){ce(r,n,{state:`error`,detail:e instanceof Error?e.message:t(`api.testFailed`)})}},ue=t(`api.subtitle`).split(`{authHeader}`);return(0,z.jsxs)(`section`,{className:`api-page`,"aria-busy":M.refreshing||N.refreshing||void 0,children:[(0,z.jsx)(`div`,{className:`page-head`,children:(0,z.jsx)(`h2`,{children:t(`api.title`)})}),(0,z.jsxs)(`p`,{className:`page-sub`,children:[ue[0],(0,z.jsx)(`code`,{children:`x-opencodex-api-key`}),ue[1]]}),u&&(0,z.jsx)(q,{tone:`err`,children:u}),M.showError&&P&&(0,z.jsx)(q,{tone:`err`,children:t(`api.keysLoadFailed`)}),M.showSkeleton&&!P?(0,z.jsx)(fs,{label:t(`api.activeKeysLoading`),rows:4}):M.kind===`failed-cold`&&!P?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(q,{tone:`err`,children:M.error instanceof Error?M.error.message:t(`api.keysLoadFailed`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>U(),children:t(`common.retry`)})]}):(0,z.jsx)(z.Fragment,{children:(0,z.jsx)(Ku,{keys:I,apiBase:e,attributionSince:B,historyTruncated:V,authMatrix:H,keysLoading:!1,keysLoadFailed:M.showError,endpoints:L,claudeCodeEnabled:R,localeTag:r,newName:y,creating:x,newKey:C,copied:T,filteredModels:ee,modelsLoading:N.showSkeleton&&!N.data&&!l,modelsRefreshing:N.refreshing&&N.showError&&(N.data!==void 0||l!==null),modelsLoadFailed:N.showError,modelCount:F.length,hasModelData:N.data!==void 0||l!==null,modelQuery:f,copiedModelId:m,modelTests:g,onNewNameChange:b,onCreate:()=>{te()},onDismissNewKey:()=>w(null),onCopyKey:()=>{G()},onDelete:ne,onRename:re,onModelQueryChange:p,onCopyModelId:e=>{ie(e)},onTestModel:(e,t)=>{le(e,t)},onRetryModels:()=>{W({forceLoading:!0})},canTestModels:C!==null,sourceLabel:ae,protocolLabel:oe})})]})}function Qu(e,t){let n=(e??[]).map(e=>({value:e,label:zo(e)}));return[{value:``,label:t},...n]}function $u(e){let t=e.autoConnectSupported===!0;return{autoConnectSupported:t,systemEnv:t&&e.systemEnv===!0}}var ed=[`ANTHROPIC_MODEL`,`ANTHROPIC_DEFAULT_OPUS_MODEL`,`ANTHROPIC_DEFAULT_SONNET_MODEL`,`ANTHROPIC_DEFAULT_HAIKU_MODEL`,`ANTHROPIC_DEFAULT_FABLE_MODEL`];function td(e){let t=`http://127.0.0.1:${e.port}`,n=e.authMode===`auto`?e.markerMode??`subscription`:e.authMode,r=e.autoContext&&e.maxContextTokens===null,i=ed.filter(t=>e.effectiveModelEnv[t]).map(t=>`export ${t}=${e.effectiveModelEnv[t]}`);return[`export ANTHROPIC_BASE_URL=${t}`,...n===`proxy`?[`export ANTHROPIC_AUTH_TOKEN=opencodex-proxy`]:[`# no ANTHROPIC_AUTH_TOKEN: your claude.ai login (and connectors) stay active`],`export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`,...n===`proxy`?['[ -z "${CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST+x}" ] && export CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1']:[],...r?[`export CLAUDE_CODE_AUTO_COMPACT_WINDOW=${e.autoCompactWindow??35e4}`]:[],...i,`claude`].join(`
|
|
67
|
-
`)}function nd(e){return e?e.backend??`auto`:`inherit`}function rd(e,t){if(t!==`inherit`)return t===`auto`?{...e,backend:void 0}:{...e,backend:t}}function id(e,t){return{...e,model:t}}function ad(e){if(!e)return null;let t=(e.model??``).trim();return e.backend?{backend:e.backend,model:t}:t?{backend:null,model:t}:null}function od({label:e,checked:t,onChange:n,disabled:r=!1,describedBy:i}){return(0,z.jsxs)(`label`,{className:`toggle`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:t,disabled:r,"aria-label":e,"aria-describedby":i,onChange:e=>n(e.target.checked)}),(0,z.jsx)(`span`,{className:`slider`,"aria-hidden":`true`})]})}function sd({supported:e,checked:t,onChange:n}){let r=K(),i=e?void 0:`claude-system-env-unsupported`;return(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:r(`claude.systemEnv`)}),e?(0,z.jsx)(`span`,{className:`desc`,children:r(`claude.systemEnvDesc`)}):(0,z.jsx)(`span`,{className:`desc`,id:i,children:(0,z.jsx)(Ue,{k:`claude.systemEnvUnsupported`,cmd:`ocx claude`})}),e&&t&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--red)`},children:r(`claude.systemEnvWarn`)})]}),(0,z.jsx)(od,{label:r(`claude.systemEnv`),checked:e&&t,disabled:!e,describedBy:i,onChange:n})]})}function cd({value:e,tierHaikuModel:t,options:n,onChange:r}){let i=K(),a=t??e;return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:i(`claude.smallFastModelAccurateHint`)}),(0,z.jsx)(at,{value:e,options:n,onChange:r,label:i(`claude.smallFastModel`),style:{maxWidth:420}}),a===``&&(0,z.jsx)(`p`,{className:`notice-warn`,role:`status`,style:{marginTop:8},children:i(`claude.smallFastModelNativeWarning`)})]})}function ld(){if(typeof crypto<`u`&&typeof crypto.randomUUID==`function`)try{return crypto.randomUUID()}catch{}let e=new Uint8Array(16);if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`)crypto.getRandomValues(e);else for(let t=0;t<16;t++)e[t]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function ud(e,t=`en`){if(e>=1e6){let n=e/1e6,r=n.toFixed(1).replace(/\.0$/,``);return Number.isInteger(n)||Number(r)*1e6===e?new Intl.NumberFormat(t,{notation:`compact`,compactDisplay:`short`,maximumFractionDigits:+!Number.isInteger(n)}).format(e):`${Math.round(e/1e3)}k`}return`${Math.round(e/1e3)}k`}function dd(e,t){return e&&[`claude-json-oauth`,`claude-credentials-file`,`macos-keychain`,`exported-env`].includes(e)?t(`claude.authSource.${e}`):t(`claude.authSource.unknown`)}function fd({state:e,autoCompactOptions:t,availableModels:n,onStateChange:r}){let i=K();return(0,z.jsxs)(`div`,{className:`card`,style:{overflow:`hidden`},children:[(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.enabledLabel`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.enabledHint`)})]}),(0,z.jsx)(od,{label:i(`claude.enabledLabel`),checked:e.enabled,onChange:t=>r({...e,enabled:t})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.authMode`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.authModeHint`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.authMode,options:[{value:`auto`,label:i(`claude.authModeAuto`)},{value:`subscription`,label:i(`claude.authModeSubscription`)},{value:`proxy`,label:i(`claude.authModeProxy`)}],onChange:t=>r({...e,authMode:t}),label:i(`claude.authMode`),style:{minWidth:220},align:`right`,portal:!0})})]}),e.authModeOrigin&&(0,z.jsxs)(`div`,{className:`claude-effective-auth${e.authModeOrigin===`auto-unknown`?` warn`:``}`,role:`status`,children:[(0,z.jsx)(`span`,{className:`claude-effective-auth-label`,children:i(`claude.effectiveMode.label`)}),(0,z.jsxs)(`span`,{children:[e.authModeOrigin===`manual`?i(`claude.effectiveMode.manual`,{mode:e.markerMode===`proxy`?i(`claude.authModeProxy`):i(`claude.authModeSubscription`)}):e.authModeOrigin===`auto-present`?i(`claude.effectiveMode.autoPresent`,{source:dd(e.authFoundBy,i)}):e.authModeOrigin===`auto-absent`?i(`claude.effectiveMode.autoAbsent`):i(`claude.effectiveMode.autoUnknown`),e.admissionKeyActive===!0?` ${i(`claude.effectiveMode.admissionKey`)}`:``]})]}),(0,z.jsx)(sd,{supported:e.autoConnectSupported,checked:e.systemEnv,onChange:t=>r({...e,systemEnv:t})}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.fastMode`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.fastModeDesc`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.fastMode===null?`auto`:e.fastMode?`on`:`off`,options:[{value:`auto`,label:i(`claude.fastAuto`)},{value:`on`,label:i(`claude.fastOn`)},{value:`off`,label:i(`claude.fastOff`)}],onChange:t=>r({...e,fastMode:t===`auto`?null:t===`on`}),label:i(`claude.fastMode`),style:{minWidth:140},align:`right`,portal:!0})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.autoContext`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.autoContextDesc`)}),e.maxContextTokens!==null&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--muted)`},children:i(`claude.autoContextInert`)})]}),(0,z.jsx)(od,{label:i(`claude.autoContext`),checked:e.autoContext,onChange:t=>r({...e,autoContext:t})})]}),e.autoContext&&(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.autoCompactWindow`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.autoCompactWindowDesc`)}),e.autoCompactWindow!==null&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--red)`},children:i(`claude.autoCompactWindowWarn`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.autoCompactWindow===null?``:String(e.autoCompactWindow),options:t,onChange:t=>r({...e,autoCompactWindow:t===``?null:Number(t)}),label:i(`claude.autoCompactWindow`),style:{minWidth:130},align:`right`,portal:!0})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.injectAgents`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.injectAgentsDesc`)})]}),(0,z.jsx)(od,{label:i(`claude.injectAgents`),checked:e.injectAgents,onChange:t=>r({...e,injectAgents:t})})]}),[`webSearchSidecar`,`visionSidecar`].map(t=>{let a=e[t],o=t===`webSearchSidecar`?`claude.webSearchSidecar`:`claude.visionSidecar`,s=t===`webSearchSidecar`?`claude.webSearchSidecarHint`:`claude.visionSidecarHint`,c=`claude-sidecar-models-${t}`;return(0,z.jsxs)(`div`,{className:`setting-row`,style:{alignItems:`flex-start`},children:[(0,z.jsxs)(`div`,{className:`setting-label setting-copy`,style:{flex:1},children:[(0,z.jsx)(`span`,{className:`title`,children:i(o)}),(0,z.jsx)(`span`,{className:`desc`,children:i(s)})]}),(0,z.jsxs)(`div`,{className:`setting-controls`,style:{display:`flex`,gap:8},children:[(0,z.jsx)(at,{value:nd(a),options:[{value:`inherit`,label:i(`claude.useMainSetting`)},{value:`auto`,label:i(`dash.backendAuto`)},{value:`openai`,label:i(`dash.backendOpenAI`)},{value:`anthropic`,label:i(`dash.backendAnthropic`)}],onChange:n=>{r({...e,[t]:rd(a,n)})},label:i(`dash.sidecarBackend`),portal:!0}),(0,z.jsx)(`input`,{className:`input mono`,value:a?.model??``,onChange:n=>{r({...e,[t]:id(a,n.target.value)})},placeholder:i(`claude.sidecarModelPlaceholder`),disabled:!a,list:a?c:void 0,"aria-label":i(`dash.sidecarModel`),style:{minWidth:210},autoComplete:`off`}),a&&(0,z.jsx)(`datalist`,{id:c,children:n.map(e=>(0,z.jsx)(`option`,{value:e},e))})]})]},t)})]})}function pd({manualEnv:e}){let t=K();return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:(0,z.jsx)(Ue,{k:`claude.quickstartHint`,cmd:`ocx claude`})}),(0,z.jsx)(`pre`,{className:`mono card`,style:{padding:`10px 14px`,overflowX:`auto`,margin:0},children:`ocx claude`}),(0,z.jsxs)(`details`,{style:{margin:`10px 0 0`},children:[(0,z.jsx)(`summary`,{className:`muted text-label`,style:{cursor:`pointer`,padding:`2px 2px`},children:t(`claude.manualEnv`)}),(0,z.jsx)(`pre`,{className:`mono card text-label`,style:{padding:`10px 14px`,overflowX:`auto`,margin:`6px 0 0`},children:e})]})]})}function md({rows:e,onRowsChange:t}){let n=K();return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:n(`claude.modelMapHint`)}),(0,z.jsx)(`div`,{className:`stack`,style:{gap:8},children:e.map((r,i)=>(0,z.jsxs)(`div`,{className:`row`,style:{gap:8},children:[(0,z.jsx)(`input`,{className:`input mono`,value:r.from,placeholder:n(`claude.mapFrom`),"aria-label":n(`claude.mapFrom`),onChange:n=>t(e.map((e,t)=>t===i?{...e,from:n.target.value}:e)),style:{flex:1}}),(0,z.jsx)(`span`,{className:`muted`,"aria-hidden":!0,children:`→`}),(0,z.jsx)(`input`,{className:`input mono`,value:r.to,placeholder:n(`claude.mapTo`),"aria-label":n(`claude.mapTo`),onChange:n=>t(e.map((e,t)=>t===i?{...e,to:n.target.value}:e)),style:{flex:1}}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-icon btn-sm`,onClick:()=>t(e.filter((e,t)=>t!==i)),"aria-label":n(`claude.removeMapping`),style:{color:`var(--red)`},children:(0,z.jsx)(ae,{})})]},r.id))}),(0,z.jsx)(`div`,{style:{marginTop:8},children:(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>t([...e,{id:ld(),from:``,to:``}]),children:[(0,z.jsx)(oe,{}),` `,n(`claude.addMapping`)]})})]})}var hd=`etc`;function gd(e){let t=new Map;for(let n of e){let e=/\(([^)]+)\)\s*$/.exec(n.display_name),r=e?e[1]:hd,i=t.get(r);i?i.push(n):t.set(r,[n])}return Array.from(t)}function _d({aliases:e}){let t=K();return(0,z.jsxs)(`div`,{className:`claude-aliases`,children:[(0,z.jsx)(`p`,{className:`muted text-label claude-aliases-hint`,children:t(`claude.aliasesHint`)}),e.length===0?(0,z.jsx)(`div`,{className:`muted text-label`,children:t(`claude.none`)}):(0,z.jsx)(`div`,{className:`claude-aliases-scroll`,children:gd(e).map(([e,n])=>(0,z.jsxs)(`div`,{className:`claude-aliases-group`,children:[(0,z.jsxs)(`div`,{className:`claude-aliases-group-label`,children:[e===hd?t(`claude.aliasProviderOther`):e,(0,z.jsx)(`span`,{className:`claude-aliases-group-count`,children:n.length})]}),(0,z.jsx)(`div`,{className:`claude-aliases-chips`,children:n.map(e=>(0,z.jsxs)(`span`,{className:`claude-aliases-chip`,children:[(0,z.jsx)(`code`,{className:`claude-aliases-chip-id`,children:e.id}),e.display_name?(0,z.jsx)(`span`,{className:`claude-aliases-chip-name`,children:e.display_name}):null]},e.id))})]},e))})]})}function vd({apiBase:e,active:t=!0}){let n=K(),{locale:r}=Ve(),i=Ie.find(e=>e.code===r)?.htmlLang??`en`,a=`ocx.claude-code.v1:${e}`,o=`claude-code:${e}`,s=(0,_.useMemo)(()=>Y(a),[a]),[c,l]=(0,_.useState)(()=>s?.state??null),[u,d]=(0,_.useState)(()=>s?.rows??[]),[f,p]=(0,_.useState)(!!s),[m,h]=(0,_.useState)(``),[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(`settings`),x=(0,_.useCallback)(async t=>{let r=await J(await fetch(`${e}/api/claude-code`,{signal:t}),n(`claude.loadFail`));if(!r)throw Error(n(`claude.loadFail`));let i={...r,authMode:r.authMode===`proxy`||r.authMode===`subscription`?r.authMode:`auto`,...$u(r),fastMode:r.fastMode??null,maxContextTokens:r.maxContextTokens??null,autoContext:r.autoContext!==!1,autoCompactWindow:r.autoCompactWindow??null,injectAgents:r.injectAgents!==!1,effectiveModelEnv:r.effectiveModelEnv??{}},o=Object.entries(r.modelMap??{}).map(([e,t])=>({id:ld(),from:e,to:String(t)})),s={state:i,rows:o};if(t.aborted)throw Error(`Claude Code request aborted`);return l(i),d(o),p(!0),X(a,s),s},[e,a,n]),S=us(o,[e],x,{isEmpty:()=>!1,enabled:t,initialData:s??void 0}),C=S.state,w=C.data??s,T=c??w?.state??null,E=f?u:w?.rows??u,D=(0,_.useMemo)(()=>Qu(T?.available,n(`claude.smallFastModelUnsetOption`)),[T?.available,n]),O=(0,_.useMemo)(()=>{let e=[1e5,2e5,25e4,3e5,35e4,4e5,5e5,6e5,75e4,9e5,1e6],t=T?.autoCompactWindow??null,r=t!==null&&!e.includes(t)?[...e,t].sort((e,t)=>e-t):e;return[{value:``,label:n(`claude.autoCompactDefault`)},...r.map(e=>({value:String(e),label:ud(e,i)}))]},[T?.autoCompactWindow,n,i]),k=async()=>{if(!T)return;h(``);let t={};for(let e of E)e.from.trim()&&e.to.trim()&&(t[e.from.trim()]=e.to.trim());try{await J(await fetch(`${e}/api/claude-code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:T.enabled,authMode:T.authMode,systemEnv:T.systemEnv,fastMode:T.fastMode,autoContext:T.autoContext,autoCompactWindow:T.autoCompactWindow,injectAgents:T.injectAgents,smallFastModel:T.smallFastModel,modelMap:t,webSearchSidecar:ad(T.webSearchSidecar),visionSidecar:ad(T.visionSidecar)})}),n(`claude.saveFailed`)),v(!0),h(n(`claude.saved`)),S.refresh()}catch(e){v(!1),h(e instanceof Error&&e.message?e.message:n(`claude.networkError`))}};if(C.kind===`disabled`&&!w)return null;if(C.showSkeleton&&!w)return(0,z.jsx)(fs,{label:n(`claude.loading`),rows:3});if(C.kind===`failed-cold`)return(0,z.jsxs)(`div`,{className:`claudecode-workspace-shell`,children:[(0,z.jsx)(q,{tone:`err`,children:C.error instanceof Error?C.error.message:n(`claude.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>S.refresh(),children:n(`common.retry`)})]});if(!T)return null;let A=[{id:`settings`,label:n(`claude.workspace.settings`),body:(0,z.jsx)(fd,{state:T,autoCompactOptions:O,availableModels:T.available??[],onStateChange:l})},{id:`quickstart`,label:n(`claude.quickstart`),body:(0,z.jsx)(pd,{manualEnv:td(T)})},{id:`smallFast`,label:n(`claude.smallFastModel`),body:(0,z.jsx)(cd,{value:T.smallFastModel,tierHaikuModel:T.tierModels?.haiku,options:D,onChange:e=>l({...T,smallFastModel:e})})},{id:`modelMap`,label:n(`claude.modelMap`),meta:String(E.length),body:(0,z.jsx)(md,{rows:E,onRowsChange:e=>{p(!0),d(e)}})},{id:`aliases`,label:n(`claude.aliases`),meta:String(T.aliases.length),body:(0,z.jsx)(_d,{aliases:T.aliases})}],j=A.find(e=>e.id===y)??A[0],M=y===`settings`||y===`smallFast`||y===`modelMap`;return(0,z.jsxs)(`div`,{className:`claudecode-workspace-shell`,children:[m&&(0,z.jsx)(q,{tone:g?`ok`:`err`,children:m}),C.showError&&(0,z.jsx)(q,{tone:`err`,children:n(`claude.loadFail`)}),(0,z.jsxs)(`div`,{className:`claudecode-workspace-root`,children:[(0,z.jsx)(`aside`,{className:`claudecode-workspace-rail`,"aria-label":n(`claude.pageTitle`),children:(0,z.jsx)(`div`,{className:`claudecode-workspace-rail-list`,children:A.map(e=>(0,z.jsx)(`button`,{type:`button`,className:`claudecode-workspace-rail-row${y===e.id?` claudecode-workspace-rail-row--selected`:``}`,onClick:()=>b(e.id),"aria-current":y===e.id?`true`:void 0,children:(0,z.jsx)(`span`,{className:`claudecode-workspace-rail-name`,children:e.label})},e.id))})}),(0,z.jsxs)(`section`,{className:`claudecode-workspace-main`,"aria-label":j.label,children:[(0,z.jsxs)(`div`,{className:`ccw-main-head`,children:[(0,z.jsxs)(`h3`,{className:`ccw-main-title`,children:[j.label,j.meta==null?null:(0,z.jsx)(`span`,{className:`count`,children:j.meta})]}),(0,z.jsx)(`div`,{className:`claudecode-workspace-save`,"data-visible":M?`true`:`false`,children:(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,disabled:!M,tabIndex:M?0:-1,"aria-hidden":!M,onClick:()=>{k()},children:n(`common.save`)})})]}),(0,z.jsx)(`div`,{className:`ccw-body`,children:j.body})]})]})]})}function $(e,t,n){let r=t.trim().toLowerCase(),i=(r?e.filter(e=>e.label.toLowerCase().includes(r)||e.route.toLowerCase().includes(r)):e).toSorted((e,t)=>Number(!e.available)-Number(!t.available)),a=i.slice(0,n);return{total:e.length,showSearch:e.length>4,shown:a,hidden:i.length-a.length,noMatch:e.length>0&&i.length===0}}function yd(e){return new Set(Object.keys(e))}function bd(e,t){return t!==null&&e===t}function xd(e){return e||(typeof localStorage>`u`?void 0:localStorage)}function Sd(e){return{read(t){let n=xd(t);if(!n)return null;try{let t=n.getItem(e);if(t===null)return null;let r=JSON.parse(t);return Array.isArray(r)?new Set(r.filter(e=>typeof e==`string`)):null}catch{return null}},write(t,n){let r=xd(n);if(r)try{r.setItem(e,JSON.stringify([...t]))}catch{}}}}function Cd(e,t){let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n}var wd=[`opus`,`fable`,`sonnet`,`haiku`],Td=Sd(`ocx.claudeDesktop.collapsedFamilies.v2`),Ed={opus:`claudeDesktop.family.opus`,fable:`claudeDesktop.family.fable`,sonnet:`claudeDesktop.family.sonnet`,haiku:`claudeDesktop.family.haiku`};function Dd(e){return{version:1,assignments:Object.fromEntries(Object.entries(e.assignments).map(([e,t])=>[e,{...t}])),defaults:{...e.defaults},...e.appliedFingerprint===void 0?{}:{appliedFingerprint:e.appliedFingerprint},...e.appliedAt===void 0?{}:{appliedAt:e.appliedAt}}}function Od(e){let t={...e.profile.assignments};for(let n of e.models){let e=t[n.route]??n.assignment;t[n.route]={family:wd.includes(e?.family)?e.family:`opus`,alias:typeof e?.alias==`string`?e.alias:``}}return{version:1,assignments:t,defaults:{opus:e.profile.defaults.opus??null,fable:e.profile.defaults.fable??null,sonnet:e.profile.defaults.sonnet??null,haiku:e.profile.defaults.haiku??null}}}function kd(e,t){return e&&typeof e==`object`&&`error`in e&&typeof e.error==`string`?e.error:t}function Ad(e,t){return e?e>=1048576?t(`claudeDesktop.contextM`,{n:Math.round(e/1048576)}):e>=1e6?t(`claudeDesktop.contextM`,{n:e/1e6}):t(`claudeDesktop.contextK`,{n:Math.round(e/1e3)}):null}function jd(e){return Y(e)}function Md(e){let t=jd(e);return{held:t,data:t?.data??null,profile:t?.profile??null,savedProfile:t?.profile?Dd(t.profile):null,destinations:t?.data?Object.fromEntries(t.data.models.map(e=>[e.route,t.profile.assignments[e.route]?.family??`opus`])):{}}}function Nd({apiBase:e,active:t=!0,onPortChange:n}){let{t:r,locale:i}=Ve(),a=Ie.find(e=>e.code===i)?.htmlLang,o=`ocx.claude-desktop.v1:${e}`,s=`claude-desktop:${e}`,c=(0,_.useMemo)(()=>Md(o),[o]),[l,u]=(0,_.useState)(()=>c.profile),[d,f]=(0,_.useState)(()=>c.savedProfile),[p,m]=(0,_.useState)(()=>c.destinations),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(``),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)({}),[w,T]=(0,_.useState)({}),[E,D]=(0,_.useState)(()=>Td.read()??new Set(wd)),[O,k]=(0,_.useState)({}),A=(0,_.useRef)(null),j=(0,_.useCallback)(async t=>{let n=await J(await fetch(`${e}/api/claude-desktop`,{signal:t}),r(`claudeDesktop.loadFail`));if(!n||!(`profile`in n)||!(`models`in n))throw Error(kd(n,r(`claudeDesktop.loadFail`)));let i=Od(n),a={data:n,profile:i};if(t.aborted)throw Error(`Claude Desktop request aborted`);if(u(i),f(Dd(i)),m(Object.fromEntries(n.models.map(e=>[e.route,i.assignments[e.route]?.family??`opus`]))),Td.read()===null){let e=Object.fromEntries(wd.map(e=>[e,0]));for(let t of n.models)e[i.assignments[t.route]?.family??`opus`]+=1;D(yd(e))}return X(o,a),a},[e,o,r,m,u,f]),M=us(s,[e],j,{isEmpty:()=>!1,enabled:t,initialData:c.held??void 0}),N=M.state,P=N.data??(c.data&&c.profile?{data:c.data,profile:c.profile}:null),F=P?.data??null,I=l??P?.profile??null,L=d??P?.profile??null,R=P?Object.fromEntries(P.data.models.map(e=>[e.route,P.profile.assignments[e.route]?.family??`opus`])):{},B=Object.keys(p).length>0?p:R;(0,_.useEffect)(()=>{if(n){if(typeof F?.port==`number`){n(F.port);return}N.kind===`failed-cold`&&n(null)}},[F?.port,N.kind,n]);let V=(0,_.useMemo)(()=>I!==null&&L!==null&&JSON.stringify(I)!==JSON.stringify(L),[I,L]),H=(0,_.useMemo)(()=>{let e=Object.fromEntries(wd.map(e=>[e,[]]));if(!F||!I)return e;for(let t of F.models)e[I.assignments[t.route]?.family??`opus`].push(t);return e},[F,I]),U=(0,_.useMemo)(()=>{let e={};for(let t of wd){let n=H[t].filter(e=>e.available).map(e=>e.route).sort(),r=I?.defaults[t]??null;e[t]=r&&n.includes(r)?r:n[0]??null}return e},[H,I]),W=`ocx.claude-desktop.status.v1:${e}`,ee=`claude-desktop-status:${e}`,te=Y(W),ne=us(ee,[e],async t=>{let n=await ut(await fetch(`${e}/api/claude-desktop/status`,{signal:t}));if(!n)throw Error(`Claude Desktop status unavailable`);return X(W,n),n},{isEmpty:()=>!1,pollMs:5e3,enabled:t,initialData:te??void 0}),re=ne.state,G=re.data??te??null,ie=re.showError,ae=(e,t)=>{!I||I.assignments[e]?.family===t||(u(n=>{if(!n)return n;let r=n.assignments[e];if(!r||r.family===t)return n;let i={...n.assignments,[e]:{...r,family:t}},a={...n.defaults};return a[r.family]===e&&(a[r.family]=Object.keys(i).filter(t=>t!==e&&i[t].family===r.family).sort()[0]??null),a[t]===null&&(a[t]=e),{...n,assignments:i,defaults:a}}),m(n=>({...n,[e]:t})),y(r(`claudeDesktop.moved`,{route:e,family:r(Ed[t])})))},oe=e=>{let t=Cd(E,e);Td.write(t),D(t)},se=async t=>{if(!(!I||b)){x(`save`),g(null);try{await J(await fetch(`${e}/api/claude-desktop`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({profile:I})}),r(`claudeDesktop.saveFailed`)),f(Dd(I)),t?(x(`apply`),await J(await fetch(`${e}/api/claude-desktop/apply`,{method:`POST`}),r(`claudeDesktop.applyFailed`)),g({tone:`ok`,text:r(`claudeDesktop.savedApplied`)}),y(r(`claudeDesktop.savedAppliedAnnounce`))):(g({tone:`ok`,text:r(`claudeDesktop.saved`)}),y(r(`claudeDesktop.savedAnnounce`))),ne.refresh()}catch(e){let t=e instanceof Error?e.message:r(`claudeDesktop.updateFailed`);g({tone:`err`,text:t}),y(t)}finally{x(null)}}},ce=()=>{if(!I)return;let e=URL.createObjectURL(new Blob([`${JSON.stringify(I,null,2)}\n`],{type:`application/json`})),t=document.createElement(`a`);t.href=e,t.download=`claude-desktop-profile.json`,t.click(),URL.revokeObjectURL(e),y(r(`claudeDesktop.exported`))},le=async e=>{let t=e.target.files?.[0];if(e.target.value=``,t)try{let e=JSON.parse(await t.text());if(e.version!==1||!e.assignments||!e.defaults)throw Error(r(`claudeDesktop.importExpected`));u(Od({...F,profile:e})),g({tone:`ok`,text:r(`claudeDesktop.importReady`)}),y(r(`claudeDesktop.importedAnnounce`))}catch(e){let t=e instanceof Error?e.message:r(`claudeDesktop.importInvalid`);g({tone:`err`,text:t}),y(r(`claudeDesktop.importFailed`,{error:t}))}},ue=(e,t)=>{e.preventDefault();let n=e.dataTransfer.getData(`text/plain`);n&&ae(n,t)};return N.kind===`disabled`&&!P?null:N.showSkeleton&&!P?(0,z.jsx)(fs,{label:r(`claudeDesktop.loading`),rows:4}):N.kind===`failed-cold`?(0,z.jsxs)(`div`,{className:`claude-desktop-error`,children:[(0,z.jsx)(q,{tone:`err`,children:N.error instanceof Error?N.error.message:r(`claudeDesktop.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,onClick:()=>M.refresh(),children:r(`claudeDesktop.retry`)})]}):!F||!I?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`div`,{className:`claude-desktop-toolbar`,children:(0,z.jsxs)(`div`,{className:`claude-profile-tools`,children:[(0,z.jsx)(`input`,{ref:A,type:`file`,accept:`application/json,.json`,hidden:!0,onChange:e=>void le(e)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A.current?.click(),children:r(`claudeDesktop.importJson`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:ce,children:r(`claudeDesktop.exportJson`)})]})}),(0,z.jsxs)(`div`,{className:`claude-status-bar ${ie&&!G?`not-applied`:G?G.activeProfile===!1?`not-applied`:G.stale?`stale`:G.applied?`applied`:`not-applied`:`pending`}`,"aria-busy":!G&&!ie||void 0,children:[(0,z.jsx)(`span`,{className:`claude-status-dot`}),(0,z.jsx)(`span`,{children:ie&&!G?r(`claudeDesktop.loadFail`):G?G.activeProfile===!1?r(`claudeDesktop.status.notActiveProfile`):G.stale?r(`claudeDesktop.status.stale`):G.applied?r(`claudeDesktop.status.applied`):r(`claudeDesktop.status.notApplied`):r(`claudeDesktop.loading`)}),G?.health.lastRequestAt&&(0,z.jsxs)(`span`,{className:`claude-status-health`,children:[r(`claudeDesktop.health.lastRequest`),`:`,` `,new Date(G.health.lastRequestAt).toLocaleTimeString(a)]}),G&&G.health.requestCount>0&&(0,z.jsx)(`span`,{className:`claude-status-health`,children:r(`claudeDesktop.health.stats`,{count:G.health.requestCount,errors:G.health.errorCount})})]}),(0,z.jsx)(`div`,{className:`sr-only`,"aria-live":`polite`,"aria-atomic":`true`,children:v}),h&&(0,z.jsx)(q,{tone:h.tone,children:h.text}),N.showError&&(0,z.jsx)(q,{tone:`err`,children:r(`claudeDesktop.loadFail`)}),ie&&G&&(0,z.jsx)(q,{tone:`err`,children:r(`claudeDesktop.loadFail`)}),(0,z.jsxs)(`div`,{className:`claude-profile-bar`,children:[(0,z.jsx)(`span`,{className:`claude-dirty${V?` active`:``}`,children:r(V?`claudeDesktop.unsaved`:`claudeDesktop.upToDate`)}),(0,z.jsxs)(`div`,{className:`claude-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:!V||b!==null,onClick:()=>void se(!1),children:r(b===`save`?`claudeDesktop.saving`:`common.save`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:b!==null,onClick:()=>void se(!0),children:r(b===`apply`?`claudeDesktop.applying`:b===`save`?`claudeDesktop.saving`:`claudeDesktop.saveApply`)})]})]}),F.models.length===0&&(0,z.jsx)(ot,{title:r(`claudeDesktop.emptyTitle`),children:r(`claudeDesktop.emptyHint`)}),(0,z.jsx)(`div`,{className:`ocx-group-stack`,"aria-label":r(`claudeDesktop.assignmentsLabel`),children:wd.map(e=>{let t=H[e],n=$(t,S[e]??``,w[e]??6),i=E.has(e),a=U[e];return(0,z.jsxs)(`section`,{className:`ocx-group${i?` collapsed`:``}`,"aria-labelledby":`claude-lane-${e}`,onDragOver:e=>e.preventDefault(),onDrop:t=>ue(t,e),children:[(0,z.jsxs)(`header`,{className:`ocx-group-head${i?``:` open`}`,children:[(0,z.jsx)(`h3`,{id:`claude-lane-${e}`,className:`ocx-group-heading`,children:(0,z.jsxs)(`button`,{type:`button`,className:`ocx-group-toggle`,"aria-expanded":!i,"aria-controls":`claude-lane-body-${e}`,onClick:()=>oe(e),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:14,height:14,"aria-hidden":`true`,style:{transform:i?`none`:`rotate(90deg)`}}),(0,z.jsx)(`span`,{className:`ocx-group-name`,children:r(Ed[e])}),(0,z.jsx)(`span`,{className:`ocx-group-count`,children:r(t.length===1?`claudeDesktop.modelCountOne`:`claudeDesktop.modelCountMany`,{count:t.length})}),a&&(0,z.jsx)(`code`,{className:`claude-lane-default`,title:a,children:a})]})}),t.length>0&&I.defaults[e]===null&&(0,z.jsx)(`span`,{className:`claude-default-needed`,children:r(`claudeDesktop.chooseDefault`)}),a&&a!==I.defaults[e]&&(0,z.jsx)(`span`,{className:`claude-default-needed`,title:a,children:r(`claudeDesktop.temporaryDefault`)})]}),!i&&(0,z.jsxs)(`div`,{id:`claude-lane-body-${e}`,children:[n.showSearch&&(0,z.jsx)(`input`,{className:`input claude-lane-search`,type:`search`,placeholder:r(`models.search`),"aria-label":r(`models.search`),value:S[e]??``,onChange:t=>{let n=t.target.value;C(t=>({...t,[e]:n})),T(t=>({...t,[e]:6}))}}),(0,z.jsxs)(`div`,{className:`claude-lane-models`,children:[t.length===0?(0,z.jsx)(`div`,{className:`claude-lane-empty`,children:r(`claudeDesktop.laneEmpty`)}):n.noMatch?(0,z.jsx)(`div`,{className:`claude-lane-empty`,children:r(`claudeDesktop.laneNoMatch`)}):n.shown.map(t=>{let n=I.assignments[t.route],i=Ad(t.contextWindow,r),a=B[t.route]??`opus`,o=O[t.route]??bd(t.route,U[e]);return(0,z.jsxs)(`article`,{className:`claude-model-card${o?` open`:``}`,draggable:t.available,onDragStart:e=>{e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,t.route)},children:[(0,z.jsxs)(`button`,{type:`button`,className:`claude-model-summary`,"aria-expanded":o,"aria-controls":`claude-model-body-${t.route}`,onClick:()=>k(e=>({...e,[t.route]:!o})),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:12,height:12,"aria-hidden":`true`,style:{transform:o?`rotate(90deg)`:`none`}}),(0,z.jsxs)(`span`,{className:`claude-model-names`,children:[(0,z.jsx)(`strong`,{title:t.label,children:t.label}),(0,z.jsx)(`code`,{title:t.route,children:t.route})]}),i&&(0,z.jsx)(`span`,{className:`claude-model-context`,children:i}),!i&&(0,z.jsx)(`span`,{className:`claude-model-context claude-model-context-unknown`,children:r(`claudeDesktop.contextUnknown`)}),t.supports1m===!0&&(0,z.jsx)(`span`,{className:`claude-1m-chip`,children:r(`claudeDesktop.supports1m`)}),t.effortSupported===!1&&(0,z.jsx)(`span`,{className:`claude-effort-badge off`,children:r(`claudeDesktop.effort.displayOnly`)}),t.effortSupported===!0&&(0,z.jsx)(`span`,{className:`claude-effort-badge on`,children:r(`claudeDesktop.effort.supported`)}),I.defaults[e]===t.route&&(0,z.jsx)(`span`,{className:`claude-row-default`,children:r(`claudeDesktop.defaultBadge`)}),(0,z.jsx)(`span`,{className:`badge ${t.available?`badge-green`:`badge-muted`}`,children:t.available?r(`claudeDesktop.available`):r(`claudeDesktop.unavailable`)})]}),o&&(0,z.jsxs)(`div`,{className:`claude-model-body`,id:`claude-model-body-${t.route}`,children:[U[e]===t.route&&I.defaults[e]!==t.route&&(0,z.jsx)(`span`,{className:`claude-effective-default`,children:r(`claudeDesktop.temporaryDefault`)}),(0,z.jsxs)(`div`,{className:`claude-field`,children:[(0,z.jsx)(`span`,{children:r(`claudeDesktop.alias`)}),(0,z.jsx)(`code`,{className:`claude-alias`,title:n.alias,children:n.alias})]}),(0,z.jsxs)(`label`,{className:`claude-default-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`default-${e}`,checked:I.defaults[e]===t.route,disabled:!t.available,onChange:()=>u(n=>n&&{...n,defaults:{...n.defaults,[e]:t.route}})}),r(`claudeDesktop.useAsDefault`,{family:r(Ed[e])})]}),(0,z.jsxs)(`div`,{className:`claude-move-row`,children:[(0,z.jsx)(`label`,{htmlFor:`move-${t.route}`,children:r(`claudeDesktop.moveTo`)}),(0,z.jsx)(`select`,{id:`move-${t.route}`,className:`input`,value:a,disabled:!t.available,onChange:e=>m(n=>({...n,[t.route]:e.target.value})),children:wd.map(e=>(0,z.jsx)(`option`,{value:e,children:r(Ed[e])},e))}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,disabled:!t.available||a===e,onClick:()=>ae(t.route,a),children:r(`claudeDesktop.move`)})]})]})]},t.route)}),n.hidden>0&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm claude-lane-more`,onClick:()=>T(t=>({...t,[e]:(t[e]??6)+6})),children:r(`models.showMore`,{n:n.hidden})})]})]})]},e)})})]})}function Pd(e){let t=Y(`ocx.claude-desktop.v1:${e}`);return typeof t?.data?.port==`number`?t.data.port:null}function Fd({apiBase:e}){let[t,n]=(0,_.useState)(`code`),r=K(),i=(0,_.useRef)(null),a=(0,_.useRef)(null),o=Pd(e),[s,c]=(0,_.useState)(null),l=s?.base===e?s.port:o,u=s?.base===e,d=(0,_.useCallback)(t=>{c(n=>n?.base===e&&n.port===t?n:{base:e,port:t})},[e]),f=e=>{n(e),window.requestAnimationFrame(()=>{(e===`code`?i:a).current?.focus({preventScroll:!0})})},p=e=>{e.key===`ArrowLeft`||e.key===`ArrowRight`?(e.preventDefault(),f(t===`code`?`desktop`:`code`)):e.key===`Home`?(e.preventDefault(),f(`code`)):e.key===`End`&&(e.preventDefault(),f(`desktop`))};return(0,z.jsxs)(`section`,{className:`claude-page`,children:[(0,z.jsxs)(`div`,{className:`claude-page-intro`,children:[(0,z.jsx)(`div`,{className:`page-head`,children:(0,z.jsx)(`h2`,{children:r(t===`code`?`claude.pageTitle`:`claudeDesktop.title`)})}),t===`code`?(0,z.jsx)(`p`,{className:`page-sub`,children:r(`claude.subtitle`)}):(0,z.jsx)(`p`,{className:`page-sub`,children:l==null?r(u?`claudeDesktop.loadFail`:`claudeDesktop.loading`):r(`claudeDesktop.subtitle`,{port:l})})]}),(0,z.jsxs)(`div`,{className:`claude-tabs`,role:`tablist`,"aria-label":r(`claude.tabsLabel`),children:[(0,z.jsx)(`button`,{type:`button`,role:`tab`,ref:i,"aria-selected":t===`code`,"aria-controls":`claude-code-panel`,id:`claude-code-tab`,className:t===`code`?`active`:``,tabIndex:t===`code`?0:-1,onKeyDown:p,onClick:()=>f(`code`),children:r(`claude.tabCode`)}),(0,z.jsx)(`button`,{type:`button`,role:`tab`,ref:a,"aria-selected":t===`desktop`,"aria-controls":`claude-desktop-panel`,id:`claude-desktop-tab`,className:t===`desktop`?`active`:``,tabIndex:t===`desktop`?0:-1,onKeyDown:p,onClick:()=>f(`desktop`),children:r(`claude.tabDesktop`)})]}),(0,z.jsx)(`div`,{id:`claude-code-panel`,role:`tabpanel`,"aria-labelledby":`claude-code-tab`,hidden:t!==`code`,children:(0,z.jsx)(vd,{apiBase:e,active:t===`code`},e)}),(0,z.jsx)(`div`,{id:`claude-desktop-panel`,role:`tabpanel`,"aria-labelledby":`claude-desktop-tab`,hidden:t!==`desktop`,children:(0,z.jsx)(Nd,{apiBase:e,active:t===`desktop`,onPortChange:d},e)})]})}function Id(e,t,n,r){let i=e.filter(e=>r===`native`===e.native).map(e=>({...e,alias:t.get(e.id)??null,enabled:!n.has(e.id)})).toSorted((e,t)=>Number(!e.enabled)-Number(!t.enabled));return{rows:i,total:i.length,enabled:i.filter(e=>e.enabled).length}}var Ld=Sd(`ocx.grok.collapsedGroups.v2`),Rd=[{id:`native`,tkey:`grok.groupNative`},{id:`routed`,tkey:`grok.groupRouted`}],zd=new Set(Rd.map(e=>e.id));function Bd(e,t){return e?e>=1048576?t(`claudeDesktop.contextM`,{n:Math.round(e/1048576)}):e>=1e6?t(`claudeDesktop.contextM`,{n:e/1e6}):t(`claudeDesktop.contextK`,{n:Math.round(e/1e3)}):`—`}function Vd({apiBase:e}){let t=K(),n=`ocx.grok.status.v1:${e}`,r=Y(n),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(()=>Ld.read()??new Set(zd)),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(``),m=(0,_.useCallback)(async()=>{let r=await J(await fetch(`${e}/api/grok`),t(`grok.loadFail`));if(!r)throw Error(t(`grok.loadFail`));let i={...r,candidates:r.candidates??[],excluded:r.excluded??[]};return X(n,i),i},[e,n,t]),h=`grok-status:${e}`,g=us(h,[e],m,{isEmpty:()=>!1,initialData:r??void 0}),{state:v}=g,y=g.refresh,b=v.data??r,x=(0,_.useMemo)(()=>new Set(b?.excluded??[]),[b]),S=i??x,C=(0,_.useMemo)(()=>i!==null&&(i.size!==x.size||[...i].some(e=>!x.has(e))),[i,x]),w=(0,_.useMemo)(()=>new Map((b?.models??[]).map(e=>[e.id,e.alias])),[b]),T=e=>{let t=Cd(o,e);Ld.write(t),s(t)},E=e=>{let t=e?new Set(Rd.map(e=>e.id)):new Set;Ld.write(t),s(t)},D=(e,t)=>{a(n=>{let r=new Set(n??x);return t?r.delete(e):r.add(e),r})},O=async r=>{if(!c){l(`save`),d(null);try{await J(await fetch(`${e}/api/grok/selection`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({excluded:[...S]})}),t(`grok.saveFailed`));let i=[...S];if(b&&L(h,{...b,excluded:i}),a(null),r){l(`apply`);let n=await fetch(`${e}/api/grok/apply`,{method:`POST`});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.message??e.error??t(`grok.applyFailed`))}let r=await n.json().catch(()=>({}));r.skippedReason?(d({tone:`err`,text:r.message??t(`grok.applySkipped`)}),p(r.message??t(`grok.applySkipped`))):(d({tone:`ok`,text:t(`grok.savedApplied`)}),p(t(`grok.savedApplied`))),await y()}else d({tone:`ok`,text:t(`grok.saved`)}),p(t(`grok.saved`)),b&&X(n,{...b,excluded:i})}catch(e){let n=e instanceof Error?e.message:t(`grok.saveFailed`);d({tone:`err`,text:n}),p(n)}finally{l(null)}}};return v.showSkeleton&&!b?(0,z.jsx)(`section`,{className:`grok-page`,children:(0,z.jsx)(fs,{label:t(`grok.loading`),rows:4})}):v.kind===`failed-cold`?(0,z.jsxs)(`section`,{className:`grok-page`,children:[(0,z.jsx)(`div`,{className:`alert alert-err`,role:`alert`,children:v.error instanceof Error?v.error.message:t(`grok.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>y(),children:t(`common.retry`)})]}):(0,z.jsxs)(`section`,{className:`grok-page`,"aria-busy":v.refreshing||void 0,children:[(0,z.jsx)(`h2`,{className:`page-title`,children:t(`grok.title`)}),(0,z.jsx)(`p`,{className:`page-sub`,children:t(`grok.subtitle`)}),(0,z.jsx)(`div`,{className:`sr-only`,"aria-live":`polite`,"aria-atomic":`true`,children:f}),u&&(0,z.jsx)(q,{tone:u.tone,children:u.text}),v.showError&&(0,z.jsx)(q,{tone:`err`,children:t(`grok.loadFail`)}),b&&b.candidates.length>0&&(0,z.jsxs)(`div`,{className:`claude-profile-bar`,children:[(0,z.jsx)(`span`,{className:`claude-dirty${C?` active`:``}`,children:t(C?`grok.unsaved`:`grok.upToDate`)}),(0,z.jsxs)(`div`,{className:`claude-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:!C||c!==null,onClick:()=>void O(!1),children:t(c===`save`?`grok.saving`:`common.save`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:!C||c!==null,onClick:()=>void O(!0),children:t(c===`apply`?`grok.applying`:c===`save`?`grok.saving`:`grok.saveApply`)})]})]}),b?.present?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`div`,{className:`grok-endpoint`,children:[(0,z.jsx)(`span`,{children:t(`grok.endpoint`)}),(0,z.jsx)(`code`,{children:b.baseUrl??`—`})]}),(0,z.jsx)(`p`,{className:`page-sub`,children:(0,z.jsx)(`code`,{children:b.configPath})})]}):(0,z.jsxs)(ot,{title:t(`grok.notConfiguredTitle`),children:[t(`grok.notConfiguredHint`),(0,z.jsx)(`br`,{}),(0,z.jsx)(`code`,{children:b?.configPath})]}),b&&b.candidates.length>0&&(0,z.jsxs)(`div`,{className:`ocx-group-stack`,children:[(0,z.jsxs)(`div`,{className:`row`,style:{gap:6,margin:`2px 0 10px`},children:[(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm text-caption`,onClick:()=>E(!0),disabled:c!==null,children:[(0,z.jsx)(_e,{width:12,height:12,"aria-hidden":`true`}),` `,t(`models.collapseAll`)]}),(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm text-caption`,onClick:()=>E(!1),disabled:c!==null,children:[(0,z.jsx)(_e,{width:12,height:12,"aria-hidden":`true`,style:{transform:`rotate(90deg)`}}),` `,t(`models.expandAll`)]})]}),Rd.map(e=>{let n=Id(b.candidates,w,S,e.id);if(n.total===0)return null;let r=o.has(e.id);return(0,z.jsxs)(`section`,{className:`ocx-group${r?` collapsed`:``}`,"aria-labelledby":`grok-group-${e.id}`,children:[(0,z.jsx)(`header`,{className:`ocx-group-head${r?``:` open`}`,children:(0,z.jsx)(`h3`,{id:`grok-group-${e.id}`,className:`ocx-group-heading`,children:(0,z.jsxs)(`button`,{type:`button`,className:`ocx-group-toggle`,"aria-expanded":!r,"aria-controls":`grok-group-body-${e.id}`,onClick:()=>T(e.id),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:14,height:14,"aria-hidden":`true`,style:{transform:r?`none`:`rotate(90deg)`}}),(0,z.jsx)(`span`,{className:`ocx-group-name`,children:t(e.tkey)}),(0,z.jsx)(`span`,{className:`ocx-group-count`,children:t(`grok.enabledCount`,{on:n.enabled,total:n.total})})]})})}),!r&&(0,z.jsx)(`div`,{id:`grok-group-body-${e.id}`,className:`grok-model-list`,children:n.rows.map(e=>(0,z.jsxs)(`div`,{className:`grok-model-row`,children:[(0,z.jsx)(it,{on:e.enabled,onClick:()=>D(e.id,!e.enabled),disabled:c!==null,label:t(`grok.toggleModel`,{id:e.id})}),(0,z.jsxs)(`span`,{className:`grok-model-names`,children:[(0,z.jsx)(`strong`,{title:e.id,children:e.id}),(0,z.jsx)(`code`,{title:e.alias??void 0,children:e.alias??`—`})]}),(0,z.jsx)(`span`,{className:`claude-model-context`,children:Bd(e.contextWindow,t)})]},e.id))})]},e.id)})]})]})}function Hd(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.supported==`boolean`&&typeof t.installed==`boolean`&&typeof t.running==`boolean`&&typeof t.stale==`boolean`&&typeof t.summary==`string`}var Ud={native:`startup.status.native`,protected:`startup.status.protected`,"at-risk":`startup.status.atRisk`},Wd={native:`startup.summary.native`,protected:`startup.summary.protected`,"at-risk":`startup.summary.atRisk`},Gd={service:`startup.protection.service`,shim:`startup.protection.shim`,none:`startup.protection.none`};function Kd({ok:e,yes:t,no:n}){return(0,z.jsx)(`span`,{className:`badge ${e?`badge-green`:`badge-amber`}`,children:e?t:n})}function qd({failed:e,data:t}){let{t:n}=Ve(),r=e?`startup-hero--risk`:t.status===`protected`?`startup-hero--safe`:t.status===`at-risk`?`startup-hero--risk`:`startup-hero--native`,i=e||t.status===`at-risk`?de:ie,a=t.routingKind===`opencodex-local`?`startup.routing.proxy`:t.routingKind===`custom-local`?`startup.routing.customLocal`:t.routingKind===`custom-remote`?`startup.routing.customRemote`:t.routingKind===`unknown`?`startup.routing.unknown`:`startup.routing.native`;return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`section`,{className:`panel startup-hero ${r}`,"aria-live":`polite`,children:[(0,z.jsx)(`div`,{className:`startup-hero-icon`,children:(0,z.jsx)(i,{})}),(0,z.jsxs)(`div`,{className:`startup-hero-copy`,children:[(0,z.jsx)(`span`,{className:`badge ${e||t.status===`at-risk`?`badge-amber`:`badge-green`}`,children:n(e?`startup.status.atRisk`:Ud[t.status])}),(0,z.jsx)(`h3`,{children:n(e?`startup.error`:Wd[t.status])}),(0,z.jsx)(`p`,{children:e?n(`startup.staleData`):t.status===`at-risk`?n(cn(t)):n(`startup.safeDetail`)})]})]}),(0,z.jsxs)(`div`,{className:`startup-state-grid`,children:[(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.routing`)}),(0,z.jsx)(`div`,{className:`value`,children:n(a)})]}),(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.restartProtection`)}),(0,z.jsx)(`div`,{className:`value`,children:n(Gd[t.protection])})]}),(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.preference`)}),(0,z.jsx)(`div`,{className:`value`,children:n(t.autostartEnabled?`startup.enabled`:`startup.disabled`)})]})]})]})}function Jd({data:e,failed:t,loading:n=!1,installBusy:r,installResult:i,onInstall:a}){let{t:o}=Ve(),s=e.serviceSupported&&e.serviceInstalled&&e.serviceStale&&!e.serviceConflict,c=e.shimInstalled&&!e.shimHealthy,l=r!==null||t||n;return(0,z.jsxs)(`section`,{className:`panel startup-details`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:o(`startup.details`)}),(0,z.jsx)(`span`,{className:`muted mono`,children:e.platform})]}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:o(`startup.service`)}),(0,z.jsx)(`span`,{children:o(`startup.serviceHint`)})]}),(0,z.jsxs)(`div`,{className:`startup-detail-actions`,children:[(0,z.jsx)(Kd,{ok:e.serviceViable,yes:o(`startup.viable`),no:o(e.serviceConflict?`startup.conflict`:e.serviceStale?`startup.stale`:e.serviceInstalled?`startup.unhealthy`:e.serviceSupported?`startup.notInstalled`:`startup.unsupported`)}),e.serviceSupported&&!e.serviceInstalled&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.service`)} - ${o(`startup.install`)}`,disabled:l,onClick:()=>a(`install-service`),children:o(r===`install-service`?`startup.installing`:`startup.install`)}),s&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.service`)} - ${o(`startup.repair`)}`,disabled:l,onClick:()=>a(`install-service`,{repair:!0}),children:o(r===`install-service`?`startup.repairing`:`startup.repair`)})]})]}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:o(`startup.shim`)}),(0,z.jsx)(`span`,{children:o(`startup.shimHint`)})]}),(0,z.jsxs)(`div`,{className:`startup-detail-actions`,children:[(0,z.jsx)(Kd,{ok:e.shimHealthy&&e.autostartEnabled,yes:o(e.shimCoverage===`cli-only`?`startup.cliOnly`:`startup.healthy`),no:o(e.shimInstalled?e.shimHealthy&&!e.autostartEnabled?`startup.installedDisabled`:`startup.stale`:`startup.notInstalled`)}),!e.shimInstalled&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.shim`)} - ${o(`startup.install`)}`,disabled:l,onClick:()=>a(`install-shim`),children:o(r===`install-shim`?`startup.installing`:`startup.install`)}),c&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.shim`)} - ${o(`startup.repair`)}`,disabled:l,onClick:()=>a(`install-shim`,{repair:!0}),children:o(r===`install-shim`?`startup.repairing`:`startup.repair`)})]})]}),i&&(0,z.jsx)(`div`,{className:`notice ${i.kind===`success`?`notice-ok`:`notice-warn`} startup-action-notice`,role:`status`,"aria-live":`polite`,children:i.kind===`success`?i.action===`install-service`?o(i.repair?`startup.serviceRepaired`:`startup.serviceInstalled`):o(i.repair?`startup.shimRepaired`:`startup.shimInstalled`):`${o(`startup.installFailed`)} ${i.detail??``}`})]})}function Yd({tray:e,trayLoading:t,trayError:n,trayBusy:r,onTrayAction:i}){let{t:a}=Ve();return(0,z.jsxs)(`section`,{className:`panel startup-actions`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:a(`startup.tray.title`)}),(0,z.jsx)(ye,{})]}),(0,z.jsx)(`p`,{className:`muted`,children:a(`startup.tray.hint`)}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:a(`startup.tray.login`)}),(0,z.jsx)(`span`,{children:a(`startup.tray.notProtection`)})]}),t||n||!e?(0,z.jsx)(`span`,{className:`badge badge-amber`,children:a(t?`startup.tray.loading`:`startup.tray.unavailable`)}):(0,z.jsx)(Kd,{ok:e.running&&!e.stale,yes:a(`startup.tray.running`),no:a(e.stale?`startup.tray.stale`:e.installed?`startup.tray.stopped`:`startup.tray.notInstalled`)})]}),(0,z.jsxs)(`div`,{className:`startup-tray-buttons`,children:[!t&&!n&&e&&!e.installed&&!e.stale&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:r,onClick:()=>i(`install`),children:a(`startup.tray.install`)}),!t&&!n&&e?.installed&&!e.stale&&!e.running&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:r,onClick:()=>i(`start`),children:a(`startup.tray.start`)}),!t&&!n&&e?.running&&!e.stale&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:r,onClick:()=>i(`stop`),children:a(`startup.tray.stop`)}),!t&&!n&&e&&(e.installed||e.stale)&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-danger`,disabled:r,onClick:()=>{window.confirm(a(`startup.tray.uninstall`))&&i(`uninstall`)},children:a(`startup.tray.uninstall`)})]}),(n||e?.stale)&&(0,z.jsx)(`div`,{className:`notice notice-warn startup-tray-error`,role:`alert`,children:a(`startup.tray.error`)})]})}function Xd({data:e,copied:t,onCopy:n}){let{t:r}=Ve();return(0,z.jsxs)(`section`,{className:`panel startup-actions`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:r(`startup.recovery`)}),(0,z.jsx)(ne,{})]}),(0,z.jsx)(`p`,{className:`muted`,children:r(`startup.recoveryHint`)}),(0,z.jsxs)(`div`,{className:`startup-command-list`,children:[e.serviceSupported&&(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.service`)}),(0,z.jsx)(`code`,{children:e.commands.installService})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.installService),children:t===e.commands.installService?r(`startup.copied`):r(`startup.copy`)})]}),(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.shim`)}),(0,z.jsx)(`code`,{children:e.commands.installShim})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.installShim),children:t===e.commands.installShim?r(`startup.copied`):r(`startup.copy`)})]}),(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.native`)}),(0,z.jsx)(`code`,{children:e.commands.restoreNative})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.restoreNative),children:t===e.commands.restoreNative?r(`startup.copied`):r(`startup.copy`)})]})]}),e.status===`at-risk`&&(0,z.jsxs)(`div`,{className:`notice notice-warn startup-action-notice`,role:`alert`,children:[(0,z.jsx)(ye,{}),` `,r(`startup.recommended`,{cmd:e.recommendedCommand??e.commands.installService})]})]})}var Zd=`ocx.startup.page.v1:`;function Qd(e,t){let n=t===`win32`?`; `:` && `;return e.join(n)}function $d(e,t,n){if(!e)return{warning:null,fix:null};let r=!!e.catalogClamp?.active,i=!!e.newerAvailable,a=(r?e.catalogClamp?.runtimeVersion:e.version)??e.version??`unknown`,o=(e.catalogClamp?.removedEfforts??[]).join(`, `),s=Qd([`ocx doctor --fix-codex-runtime`,`ocx sync`],n);return r?{warning:o?t(`startup.codexRuntime.clampHiddenWithEfforts`,{version:a,efforts:o}):t(`startup.codexRuntime.clampHidden`,{version:a}),fix:i?s:`ocx sync`}:i?{warning:t(`startup.codexRuntime.olderBinary`,{version:a}),fix:s}:{warning:null,fix:null}}function ef({apiBase:e}){let{t}=Ve(),n=`${Zd}${e}`,r=(0,_.useMemo)(()=>Y(n),[n]),i=`startup-page:${e}`,[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)(()=>r?.tray??null),[l,u]=(0,_.useState)(()=>!r?.data),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(null),[b,x]=(0,_.useState)(()=>r?.warning??null),[S,C]=(0,_.useState)(()=>r?.fix??null),[w,T]=(0,_.useState)(()=>!r?.data),E=(0,_.useRef)(!!r?.data),D=(0,_.useCallback)(async r=>{let i=E.current;i||(u(!0),T(!0));try{let i=fetch(`${e}/api/settings`,{signal:r}).then(async e=>e.ok?await e.json():null).catch(()=>null),a=await fetch(`${e}/api/startup-health`,{signal:r});if(!a.ok)throw Error(`fetch failed`);let o=await a.json();E.current=!0;let s=Y(n);X(n,{data:o,warning:s?.warning??null,fix:s?.fix??null,tray:s?.tray??null});let l=o.platform===`win32`?fetch(`${e}/api/windows-tray`,{signal:r}).then(async e=>{if(!e.ok)throw Error(`tray status failed`);let t=await e.json();if(!Hd(t))throw Error(`invalid tray status`);return{tray:t,error:!1}}).catch(()=>({tray:null,error:!0})):Promise.resolve({tray:null,error:!1});return Promise.all([i,l]).then(([e,i])=>{if(r.aborted)return;let a=o.platform===`win32`?i.tray:null;if(o.platform===`win32`?(c(a),m(i.error)):(c(null),m(!1)),u(!1),T(!1),e){let r=$d(e.codexRuntime,t,o.platform);x(r.warning),C(r.fix),X(n,{data:o,warning:r.warning,fix:r.fix,tray:a});return}let s=Y(n);X(n,{data:o,warning:s?.warning??null,fix:s?.fix??null,tray:a})}),o}catch(e){throw r.aborted?e:(i||(c(null),m(!0),x(null),C(null)),T(!1),u(!1),e)}},[e,n,t]),O=us(i,[e],D,{isEmpty:()=>!1,initialData:r?.data??void 0}),k=O.state,A=O.refresh,j=k.data??r?.data??null,M=k.refreshing,N=!!j?.diagnosticStale||k.showError;(0,_.useEffect)(()=>{if(!j?.diagnosticStale)return;let e=window.setTimeout(A,2e3);return()=>window.clearTimeout(e)},[j,A]);let P=async e=>{try{await navigator.clipboard.writeText(e),o(e),window.setTimeout(()=>o(t=>t===e?null:t),1600)}catch{o(null)}},F=async t=>{f(!0),m(!1);try{let n=await fetch(`${e}/api/windows-tray`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:t})});if(!n.ok)throw Error(`tray action failed`);let r=await n.json();if(!Hd(r.status))throw Error(`invalid tray action status`);c(r.status),m(!1)}catch{c(null),m(!0)}finally{f(!1)}},I=async(t,n)=>{g(t),y(null);try{let r=await fetch(`${e}/api/startup-action`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:t,repair:n?.repair===!0})});if(!r.ok){let e=await r.json().catch(()=>null);throw Error(typeof e?.error==`string`?e.error:`installation failed`)}y({kind:`success`,action:t,repair:n?.repair===!0}),A()}catch(e){y({kind:`error`,action:t,repair:n?.repair===!0,detail:e instanceof Error?e.message:String(e)})}finally{g(null)}};return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`div`,{className:`page-head`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`h2`,{children:t(`startup.title`)}),(0,z.jsx)(`p`,{className:`page-sub startup-page-sub`,children:t(`startup.subtitle`)})]}),(0,z.jsxs)(`div`,{className:`startup-page-head-actions`,children:[(0,z.jsx)(`a`,{className:`btn btn-ghost btn-sm`,href:`#dashboard`,children:t(`startup.backToDashboard`)}),(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A(),disabled:M,children:[(0,z.jsx)(se,{}),` `,t(`startup.refresh`)]})]})]}),k.showSkeleton&&!j?(0,z.jsx)(fs,{label:t(`startup.loading`),rows:5}):k.kind===`failed-cold`?(0,z.jsxs)(`div`,{className:`startup-page-notice`,children:[(0,z.jsx)(q,{tone:`err`,children:k.error instanceof Error?k.error.message:t(`startup.error`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A(),children:t(`common.retry`)})]}):j?(0,z.jsxs)(z.Fragment,{children:[k.showError&&(0,z.jsx)(q,{tone:`err`,children:t(`startup.error`)}),N&&(0,z.jsx)(`div`,{className:`notice notice-warn startup-page-notice`,role:`alert`,children:t(`startup.staleData`)}),(w||b)&&(0,z.jsx)(`div`,{className:`startup-runtime-notice-slot${w&&!b?` startup-runtime-notice-slot--pending`:``}`,"aria-hidden":w&&!b?!0:void 0,children:b&&(0,z.jsxs)(`div`,{className:`notice notice-warn startup-page-notice startup-runtime-notice`,role:`status`,children:[(0,z.jsx)(`p`,{className:`startup-runtime-notice__text`,children:b}),S&&(0,z.jsxs)(`div`,{className:`startup-runtime-notice__fix`,children:[(0,z.jsx)(`code`,{children:S}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>void P(S),children:t(a===S?`startup.copied`:`startup.copy`)})]})]})}),(0,z.jsx)(qd,{failed:N,data:j}),(0,z.jsx)(Jd,{data:j,failed:N,loading:M,installBusy:h,installResult:v,onInstall:(e,t)=>{I(e,t)}}),j.platform===`win32`&&(0,z.jsx)(Yd,{tray:s,trayLoading:l,trayError:p,trayBusy:d,onTrayAction:e=>{F(e)}}),(0,z.jsx)(Xd,{data:j,copied:a,onCopy:e=>{P(e)}})]}):null]})}var tf=class extends _.Component{state={error:null};static getDerivedStateFromError(e){return{error:e instanceof Error?e:Error(String(e))}}reload=()=>{this.setState({error:null})};render(){return this.state.error?(0,z.jsxs)(`section`,{className:`card`,role:`alert`,style:{maxWidth:720,padding:`var(--space-6)`},children:[(0,z.jsxs)(`h2`,{style:{margin:`0 0 var(--space-2)`,fontSize:`var(--text-title)`},children:[this.props.pageName,`: `,this.props.title]}),(0,z.jsx)(`p`,{className:`muted`,style:{margin:`0 0 var(--space-4)`},children:this.props.message}),(0,z.jsxs)(`p`,{style:{margin:`0 0 var(--space-5)`,overflowWrap:`anywhere`},children:[(0,z.jsxs)(`strong`,{children:[this.props.detailsLabel,`:`]}),` `,this.state.error.message]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,onClick:this.reload,children:this.props.reloadLabel})]}):this.props.children}},nf=5*6e4,rf=10*6e4,af=`https://github.com/lidge-jun/opencodex`;async function of(e,t){let n=await fetch(e,{signal:t});return n.ok?await n.json():null}function sf({apiBase:e,onOpenUpdate:t}){let n=K(),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(null),s=I(`sidebar-star:${e}`,[e],t=>of(`${e}/api/github/star`,t),{pollMs:nf}),c=I(`sidebar-update-badge:${e}`,[e],t=>of(`${e}/api/update/badge`,t),{pollMs:rf}),l=s.data?.state??null,u=a!==null&&a.basedOn===l?a.state:l??`not-starred`,d=s.data?.url??af,f=u===`starred`,p=c.data,m=p?.updateAvailable===!0,h=p?.latestVersion??null,g=()=>window.open(d,`_blank`,`noopener,noreferrer`),v=async()=>{if(!(f||r)){if(u===`unauthenticated`){g();return}i(!0);try{let t=await fetch(`${e}/api/github/star`,{method:`POST`}),n=t.ok?await t.json():null;if(n?.ok===!0){o({state:`starred`,basedOn:l});return}n?.state&&o({state:n.state,basedOn:l}),g()}catch{g()}finally{i(!1),s.refresh()}}},y=n(f?`sidebar.starred`:u===`unauthenticated`?`sidebar.starUnauthenticated`:`sidebar.star`),b=m&&h?n(`sidebar.updateAvailable`,{version:h}):n(`sidebar.checkUpdate`);return(0,z.jsxs)(`div`,{className:`sidebar-github-row`,children:[(0,z.jsxs)(`a`,{className:`sidebar-link sidebar-github-link`,href:d,target:`_blank`,rel:`noreferrer`,children:[(0,z.jsx)(ve,{}),` `,n(`common.github`)]}),(0,z.jsxs)(`div`,{className:`sidebar-github-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`sidebar-orb${f?` sidebar-orb--starred`:``}`,onClick:()=>{v()},disabled:r||f,"aria-label":y,"aria-pressed":f,title:y,children:(0,z.jsx)(Me,{"aria-hidden":`true`,...f?{fill:`currentColor`}:{}})}),(0,z.jsxs)(`button`,{type:`button`,className:`sidebar-orb${m?` sidebar-orb--update`:``}`,onClick:t,"aria-label":b,title:b,children:[(0,z.jsx)(ge,{"aria-hidden":`true`}),m&&(0,z.jsx)(`span`,{className:`sidebar-orb-dot`,"aria-hidden":`true`})]})]})]})}var cf=!1,lf=null,uf=null,df=!1,ff=`/`;function pf(e){try{let t=e instanceof Request?e.url:String(e),n=new URL(t,window.location.href);return n.origin===window.location.origin?n.pathname.startsWith(`/api/`):!1}catch{return!1}}var mf=`opencodex-api-token`,hf=null,gf=null,_f=null;function vf(){return hf}function yf(e){hf=e}function bf(){hf=null,gf=null,_f=null}function xf(e){let t=document.querySelector(`meta[name="${e}"]`),n=t?.content.trim()||null;return t?.remove(),n}function Sf(){wf(xf(`opencodex-session-token`),xf(`opencodex-session-csrf`),xf(`opencodex-session-origin`))}function Cf(e){e!=null&&vf()===e&&bf()}function wf(e,t,n){return!e?.startsWith(`ocx_session_`)||!t||n!==window.location.origin?!1:(hf=e,gf=t,_f=n,!0)}function Tf(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname="([^"]+)"/i)?.[1]===t)return n.match(/\bcontent="([^"]*)"/i)?.[1]?.trim()||null;return null}async function Ef(){if(!uf)return null;try{let e=await uf(ff,{cache:`no-store`});if(!e.ok)return null;let t=await e.text();return wf(Tf(t,`opencodex-session-token`),Tf(t,`opencodex-session-csrf`),Tf(t,`opencodex-session-origin`))?vf():null}catch{return null}}function Df(){try{sessionStorage.removeItem(mf)}catch{}}function Of(e,t,n){let r=new Headers(t?.headers??(e instanceof Request?e.headers:void 0));if(r.set(`X-OpenCodex-API-Key`,n),_f&&gf&&n.startsWith(`ocx_session_`)){r.set(`X-OpenCodex-GUI-Origin`,_f);let n=(t?.method??(e instanceof Request?e.method:`GET`)).toUpperCase();n!==`GET`&&n!==`HEAD`&&r.set(`X-OpenCodex-CSRF-Token`,gf)}return e instanceof Request?[new Request(e,{headers:r}),t?{...t,headers:r}:void 0]:[e,{...t,headers:r}]}async function kf(e){return df?null:lf||(lf=(async()=>{if(df)return null;let t=vf();if(t&&t!==e)return t;let n=await Ef();if(n)return n;let r=window.prompt(`OpenCodex admin token (OPENCODEX_ADMIN_AUTH_TOKEN)`)?.trim()||null;return r?(yf(r),r):(df=!0,null)})().finally(()=>{lf=null}),lf)}function Af(){if(cf)return;cf=!0,Df(),Sf();let e=window.fetch.bind(window);uf=e,window.fetch=async(t,n)=>{if(!pf(t))return e(t,n);let r=vf(),[i,a]=r?Of(t,n,r):[t,n],o=await e(i,a);if(o.status!==401)return o;let s=vf();if(s&&s!==r){let[r,i]=Of(t,n,s),a=await e(r,i);if(a.status!==401)return a;Cf(s)}else Cf(r);let c=await kf(r);if(!c)return o;let[l,u]=Of(t,n,c),d=await e(l,u);return d.status===401&&Cf(c),d}}var jf=new Set([`dashboard`,`startup`,`providers`,`models`,`combos`,`subagents`,`logs`,`usage`,`storage`,`codex-auth`,`api`,`claude`,`grok`]);function Mf(e){let t=We(e??(typeof window<`u`?window.location.hash:``)).split(`/`)[0];return t===`debug`?`logs`:jf.has(t)?t:`dashboard`}var Nf=[`dashboard/providers`,`dashboard/models`];function Pf(e,t){return e===t||t===`logs`&&e===`logs/debug`||t===`dashboard`&&(e===`dashboard/update`||Nf.includes(e))}function Ff(e){let t=Mf(e);return e===`debug`||e.startsWith(`debug/`)?{page:`logs`,replaceTo:`logs/debug`}:e===`providers/workspace`?{page:`providers`,replaceTo:`providers`}:Pf(e,t)?{page:t,replaceTo:null}:{page:t,replaceTo:t}}var If=[`ocx-global-view`,`ocx-view`,`ocx-providers-view`,`ocx-subagents-view`,`ocx-storage-view`,`ocx-codexauth-view`,`ocx-apikeys-view`,`ocx-claudecode-view`,`ocx-usage-view`,`ocx-logs-view`,`ocx-models-view`,`ocx-dashboard-view`];function Lf(){try{for(let e of If)localStorage.removeItem(e)}catch{}}function Rf(){let[e,t]=(0,_.useState)(Mf);(0,_.useEffect)(()=>{Lf()},[]);let n=(0,_.useCallback)(e=>{let n=Ff(e);n.replaceTo&&Ge(n.replaceTo),t(n.page)},[]);return(0,_.useEffect)(()=>{let e=()=>{n(We(window.location.hash))};return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[n]),(0,_.useEffect)(()=>{let t=We(window.location.hash);if(t===`debug`||t.startsWith(`debug/`)){Ge(`logs/debug`);return}if(t===`providers/workspace`){Ge(`providers`);return}Pf(t,e)||Ge(e)},[e]),{page:e,setPageState:t,navigateToPage:(e,n)=>{Ke(n?`${e}/${n}`:e),t(e)}}}var zf=15e3;function Bf(e,t,n){return typeof e?.message==`string`&&e.message.trim()?e.message:typeof e?.error==`string`&&e.error.trim()?e.error:n(t)}function Vf(e){return(e instanceof DOMException||e instanceof Error)&&e.name===`AbortError`}async function Hf(e,t={}){let{fetchFn:n=fetch,timeoutMs:r=zf,formatFailure:i=e=>`Failed to stop proxy (HTTP ${e}).`}=t,a;try{a=await n(`${e}/api/stop`,{method:`POST`,signal:AbortSignal.timeout(r)})}catch(e){return Vf(e),{accepted:!0}}let o=await a.json().catch(()=>null);return!a.ok||o?.success===!1?{accepted:!1,message:Bf(o,a.status,i)}:{accepted:!0}}Af();var Uf={dashboard:`nav.dashboard`,startup:`nav.startup`,providers:`nav.providers`,models:`nav.models`,combos:`nav.combos`,subagents:`nav.subagents`,logs:`nav.logs`,usage:`nav.usage`,storage:`nav.storage`,"codex-auth":`nav.codexAuth`,api:`nav.api`,claude:`nav.claude`,grok:`nav.grok`},Wf=``,Gf=`ocx-theme`,Kf=[{id:`dashboard`,tkey:`nav.dashboard`,Icon:V},{id:`codex-auth`,tkey:`nav.codexAuth`,Icon:xe},{id:`providers`,tkey:`nav.providers`,Icon:H},{id:`models`,tkey:`nav.models`,Icon:U},{id:`subagents`,tkey:`nav.subagents`,Icon:W},{id:`logs`,tkey:`nav.logs`,Icon:ee},{id:`usage`,tkey:`nav.usage`,Icon:re},{id:`storage`,tkey:`nav.storage`,Icon:G},{id:`api`,tkey:`nav.api`,Icon:Oe},{id:`claude`,tkey:`nav.claude`,Icon:ke},{id:`grok`,tkey:`nav.grok`,Icon:U}],qf={light:Te,dark:Ee,system:De},Jf={light:`theme.light`,dark:`theme.dark`,system:`theme.system`};function Yf(e){if(!e||typeof e!=`object`||!(`version`in e))return null;let t=e.version;return typeof t==`string`&&t.length>0?t:null}function Xf(){let e=localStorage.getItem(Gf);return e===`light`||e===`dark`?e:`system`}function Zf(){let{page:e,navigateToPage:t}=Rf(),[n,r]=(0,_.useState)(Xf),{locale:i,setLocale:a}=Ve(),o=K(),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(null),u=(0,_.useRef)(null),d=(0,_.useRef)(!1);(0,_.useEffect)(()=>{let e=()=>c(!1);return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[]),(0,_.useEffect)(()=>{let e=document.documentElement;n===`system`?(e.removeAttribute(`data-theme`),localStorage.removeItem(Gf)):(e.setAttribute(`data-theme`,n),localStorage.setItem(Gf,n))},[n]);let f=I(`app-healthz:${Wf}`,[],async e=>{let t=await fetch(`${Wf}/healthz`,{signal:e});return t.ok?Yf(await t.json()):null},{pollMs:3e4}),p=()=>r(e=>e===`light`?`dark`:e===`dark`?`system`:`light`),m=qf[n],h=f.data??`2.8.0-cs.4`,[g,v]=(0,_.useState)(!1),y=(0,_.useCallback)(async e=>{let t=await ut(await fetch(`${Wf}/api/claude-code`,{signal:e}));return t&&typeof t.enabled==`boolean`?t.enabled:null},[]),b=I(`app-claude-code:${Wf}`,[],y).data??null,x=(0,_.useRef)(!1),[S,C]=(0,_.useState)(!1);(0,_.useEffect)(()=>{if(!s)return;let e=e=>{e.key===`Escape`&&c(!1)};window.addEventListener(`keydown`,e);let t=document.body.style.overflow;return document.body.style.overflow=`hidden`,()=>{window.removeEventListener(`keydown`,e),document.body.style.overflow=t}},[s]),(0,_.useEffect)(()=>{if(s){d.current=!0;let e=setTimeout(()=>u.current?.focus(),200);return()=>clearTimeout(e)}d.current&&(d.current=!1,l.current?.focus())},[s]),(0,_.useEffect)(()=>{let e=window.matchMedia(`(min-width: 761px)`),t=()=>{e.matches&&c(!1)};return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]);let w=async()=>{if(b===null||x.current)return;x.current=!0,C(!0);let e=!b;L(`app-claude-code:${Wf}`,e);try{(await fetch(`${Wf}/api/claude-code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:e})})).ok||L(`app-claude-code:${Wf}`,!e)}catch{L(`app-claude-code:${Wf}`,!e)}finally{x.current=!1,C(!1)}},T=async()=>{if(!confirm(o(`dash.stopConfirm`)))return;v(!0);let e=await Hf(Wf,{formatFailure:e=>o(`dash.stopFailed`,{status:String(e)})});e.accepted||(v(!1),alert(e.message))},E=(0,z.jsxs)(`div`,{className:`brand`,children:[(0,z.jsx)(`span`,{className:`brand-logo`,role:`img`,"aria-label":o(`app.logoAria`)}),(0,z.jsx)(`span`,{className:`name`,children:`opencodex`}),(0,z.jsxs)(`span`,{className:`ver`,children:[`v`,h]})]});return(0,z.jsxs)(`div`,{className:`app`,children:[(0,z.jsxs)(`header`,{className:`mobile-topbar`,inert:s,children:[(0,z.jsx)(`button`,{ref:l,type:`button`,className:`menu-toggle`,onClick:()=>c(e=>!e),"aria-expanded":s,"aria-controls":`app-sidebar`,"aria-label":o(s?`nav.closeMenu`:`nav.openMenu`),title:o(s?`nav.closeMenu`:`nav.openMenu`),children:(0,z.jsx)(te,{})}),E,(0,z.jsx)(`button`,{type:`button`,className:`theme-toggle stop-toggle`,onClick:T,disabled:g,"aria-label":o(`dash.stop`),title:o(`dash.stop`),children:(0,z.jsx)(ye,{})})]}),s&&(0,z.jsx)(`div`,{className:`drawer-scrim`,onClick:()=>c(!1),"aria-hidden":`true`}),(0,z.jsxs)(`aside`,{id:`app-sidebar`,className:`sidebar${s?` open`:``}`,ref:u,tabIndex:-1,children:[(0,z.jsxs)(`div`,{className:`drawer-head`,children:[E,(0,z.jsx)(`button`,{type:`button`,className:`menu-toggle drawer-close`,onClick:()=>c(!1),"aria-label":o(`nav.closeMenu`),title:o(`nav.closeMenu`),children:(0,z.jsx)(ae,{})})]}),(0,z.jsx)(`nav`,{children:Kf.map(({id:n,tkey:r,Icon:i})=>(0,z.jsxs)(`div`,{className:`nav-entry${n===`claude`?` nav-entry-claude${e===n?` active`:``}`:``}`,children:[(0,z.jsxs)(`button`,{type:`button`,className:`nav-item${e===n?` active`:``}`,"data-page":n,onClick:()=>{t(n),c(!1)},"aria-current":e===n?`page`:void 0,children:[(0,z.jsx)(i,{}),` `,o(r)]}),n===`claude`&&b!==null&&(0,z.jsx)(it,{on:b,onClick:()=>void w(),disabled:S,label:o(`claude.toggleAria`)})]},n))}),(0,z.jsxs)(`div`,{className:`sidebar-foot`,children:[(0,z.jsxs)(`div`,{className:`lang-toggle`,children:[(0,z.jsx)(Oe,{"aria-hidden":!0}),(0,z.jsx)(at,{value:i,options:Ie.map(e=>({value:e.code,label:e.name})),onChange:e=>a(e),label:o(`lang.label`),placement:`right`,portal:!1,style:{flex:1,minWidth:0,width:`100%`}})]}),(0,z.jsxs)(`button`,{type:`button`,className:`theme-toggle`,onClick:p,"aria-label":`${o(`theme.label`)}: ${o(Jf[n])}`,title:`${o(`theme.label`)}: ${o(Jf[n])}`,children:[(0,z.jsx)(m,{}),` `,(0,z.jsx)(`span`,{className:`mode`,children:o(Jf[n])})]}),(0,z.jsxs)(`button`,{type:`button`,className:`theme-toggle stop-toggle`,onClick:T,disabled:g,"aria-label":o(`dash.stop`),title:o(`dash.stop`),children:[(0,z.jsx)(ye,{}),` `,(0,z.jsx)(`span`,{className:`mode`,children:o(g?`dash.stopping`:`dash.stop`)})]}),(0,z.jsx)(sf,{apiBase:Wf,onOpenUpdate:()=>{c(!1),t(`dashboard`,`update`)}})]})]}),(0,z.jsx)(`main`,{className:`main`,inert:s,children:(0,z.jsx)(`div`,{className:`main-inner${e===`combos`?` main-inner--combos`:``}`,children:(0,z.jsxs)(tf,{pageName:o(Uf[e]),title:o(`errorBoundary.title`),message:o(`errorBoundary.message`),detailsLabel:o(`errorBoundary.details`),reloadLabel:o(`errorBoundary.reload`),children:[e===`dashboard`&&(0,z.jsx)(Fn,{apiBase:Wf}),e===`startup`&&(0,z.jsx)(ef,{apiBase:Wf}),e===`providers`&&(0,z.jsx)(Po,{apiBase:Wf}),e===`models`&&(0,z.jsx)(Bs,{apiBase:Wf}),e===`combos`&&(0,z.jsx)(ic,{apiBase:Wf},Wf),e===`subagents`&&(0,z.jsx)(mc,{apiBase:Wf},Wf),e===`logs`&&(0,z.jsx)(Nl,{apiBase:Wf}),e===`usage`&&(0,z.jsx)(eu,{apiBase:Wf}),e===`storage`&&(0,z.jsx)(_u,{apiBase:Wf}),e===`codex-auth`&&(0,z.jsx)(xu,{apiBase:Wf}),e===`api`&&(0,z.jsx)(Zu,{apiBase:Wf}),e===`claude`&&(0,z.jsx)(Fd,{apiBase:Wf}),e===`grok`&&(0,z.jsx)(Vd,{apiBase:Wf})]},e)})})]})}g.createRoot(document.getElementById(`root`)).render((0,z.jsx)(_.StrictMode,{children:(0,z.jsx)(He,{children:(0,z.jsx)(Zf,{})})}));
|
|
67
|
+
`)}function nd(e){return e?e.backend??`auto`:`inherit`}function rd(e,t){if(t!==`inherit`)return t===`auto`?{...e,backend:void 0}:{...e,backend:t}}function id(e,t){return{...e,model:t}}function ad(e){if(!e)return null;let t=(e.model??``).trim();return e.backend?{backend:e.backend,model:t}:t?{backend:null,model:t}:null}function od({label:e,checked:t,onChange:n,disabled:r=!1,describedBy:i}){return(0,z.jsxs)(`label`,{className:`toggle`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:t,disabled:r,"aria-label":e,"aria-describedby":i,onChange:e=>n(e.target.checked)}),(0,z.jsx)(`span`,{className:`slider`,"aria-hidden":`true`})]})}function sd({supported:e,checked:t,onChange:n}){let r=K(),i=e?void 0:`claude-system-env-unsupported`;return(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:r(`claude.systemEnv`)}),e?(0,z.jsx)(`span`,{className:`desc`,children:r(`claude.systemEnvDesc`)}):(0,z.jsx)(`span`,{className:`desc`,id:i,children:(0,z.jsx)(Ue,{k:`claude.systemEnvUnsupported`,cmd:`ocx claude`})}),e&&t&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--red)`},children:r(`claude.systemEnvWarn`)})]}),(0,z.jsx)(od,{label:r(`claude.systemEnv`),checked:e&&t,disabled:!e,describedBy:i,onChange:n})]})}function cd({value:e,tierHaikuModel:t,options:n,onChange:r}){let i=K(),a=t??e;return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:i(`claude.smallFastModelAccurateHint`)}),(0,z.jsx)(at,{value:e,options:n,onChange:r,label:i(`claude.smallFastModel`),style:{maxWidth:420}}),a===``&&(0,z.jsx)(`p`,{className:`notice-warn`,role:`status`,style:{marginTop:8},children:i(`claude.smallFastModelNativeWarning`)})]})}function ld(){if(typeof crypto<`u`&&typeof crypto.randomUUID==`function`)try{return crypto.randomUUID()}catch{}let e=new Uint8Array(16);if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`)crypto.getRandomValues(e);else for(let t=0;t<16;t++)e[t]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function ud(e,t=`en`){if(e>=1e6){let n=e/1e6,r=n.toFixed(1).replace(/\.0$/,``);return Number.isInteger(n)||Number(r)*1e6===e?new Intl.NumberFormat(t,{notation:`compact`,compactDisplay:`short`,maximumFractionDigits:+!Number.isInteger(n)}).format(e):`${Math.round(e/1e3)}k`}return`${Math.round(e/1e3)}k`}function dd(e,t){return e&&[`claude-json-oauth`,`claude-credentials-file`,`macos-keychain`,`exported-env`].includes(e)?t(`claude.authSource.${e}`):t(`claude.authSource.unknown`)}function fd({state:e,autoCompactOptions:t,availableModels:n,onStateChange:r}){let i=K();return(0,z.jsxs)(`div`,{className:`card`,style:{overflow:`hidden`},children:[(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.enabledLabel`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.enabledHint`)})]}),(0,z.jsx)(od,{label:i(`claude.enabledLabel`),checked:e.enabled,onChange:t=>r({...e,enabled:t})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.authMode`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.authModeHint`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.authMode,options:[{value:`auto`,label:i(`claude.authModeAuto`)},{value:`subscription`,label:i(`claude.authModeSubscription`)},{value:`proxy`,label:i(`claude.authModeProxy`)}],onChange:t=>r({...e,authMode:t}),label:i(`claude.authMode`),style:{minWidth:220},align:`right`,portal:!0})})]}),e.authModeOrigin&&(0,z.jsxs)(`div`,{className:`claude-effective-auth${e.authModeOrigin===`auto-unknown`?` warn`:``}`,role:`status`,children:[(0,z.jsx)(`span`,{className:`claude-effective-auth-label`,children:i(`claude.effectiveMode.label`)}),(0,z.jsxs)(`span`,{children:[e.authModeOrigin===`manual`?i(`claude.effectiveMode.manual`,{mode:e.markerMode===`proxy`?i(`claude.authModeProxy`):i(`claude.authModeSubscription`)}):e.authModeOrigin===`auto-present`?i(`claude.effectiveMode.autoPresent`,{source:dd(e.authFoundBy,i)}):e.authModeOrigin===`auto-absent`?i(`claude.effectiveMode.autoAbsent`):i(`claude.effectiveMode.autoUnknown`),e.admissionKeyActive===!0?` ${i(`claude.effectiveMode.admissionKey`)}`:``]})]}),(0,z.jsx)(sd,{supported:e.autoConnectSupported,checked:e.systemEnv,onChange:t=>r({...e,systemEnv:t})}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.fastMode`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.fastModeDesc`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.fastMode===null?`auto`:e.fastMode?`on`:`off`,options:[{value:`auto`,label:i(`claude.fastAuto`)},{value:`on`,label:i(`claude.fastOn`)},{value:`off`,label:i(`claude.fastOff`)}],onChange:t=>r({...e,fastMode:t===`auto`?null:t===`on`}),label:i(`claude.fastMode`),style:{minWidth:140},align:`right`,portal:!0})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.autoContext`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.autoContextDesc`)}),e.maxContextTokens!==null&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--muted)`},children:i(`claude.autoContextInert`)})]}),(0,z.jsx)(od,{label:i(`claude.autoContext`),checked:e.autoContext,onChange:t=>r({...e,autoContext:t})})]}),e.autoContext&&(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.autoCompactWindow`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.autoCompactWindowDesc`)}),e.autoCompactWindow!==null&&(0,z.jsx)(`span`,{className:`desc`,style:{color:`var(--red)`},children:i(`claude.autoCompactWindowWarn`)})]}),(0,z.jsx)(`div`,{className:`setting-controls`,children:(0,z.jsx)(at,{value:e.autoCompactWindow===null?``:String(e.autoCompactWindow),options:t,onChange:t=>r({...e,autoCompactWindow:t===``?null:Number(t)}),label:i(`claude.autoCompactWindow`),style:{minWidth:130},align:`right`,portal:!0})})]}),(0,z.jsxs)(`div`,{className:`setting-row`,children:[(0,z.jsxs)(`div`,{className:`setting-label`,children:[(0,z.jsx)(`span`,{className:`title`,children:i(`claude.injectAgents`)}),(0,z.jsx)(`span`,{className:`desc`,children:i(`claude.injectAgentsDesc`)})]}),(0,z.jsx)(od,{label:i(`claude.injectAgents`),checked:e.injectAgents,onChange:t=>r({...e,injectAgents:t})})]}),[`webSearchSidecar`,`visionSidecar`].map(t=>{let a=e[t],o=t===`webSearchSidecar`?`claude.webSearchSidecar`:`claude.visionSidecar`,s=t===`webSearchSidecar`?`claude.webSearchSidecarHint`:`claude.visionSidecarHint`,c=`claude-sidecar-models-${t}`;return(0,z.jsxs)(`div`,{className:`setting-row`,style:{alignItems:`flex-start`},children:[(0,z.jsxs)(`div`,{className:`setting-label setting-copy`,style:{flex:1},children:[(0,z.jsx)(`span`,{className:`title`,children:i(o)}),(0,z.jsx)(`span`,{className:`desc`,children:i(s)})]}),(0,z.jsxs)(`div`,{className:`setting-controls`,style:{display:`flex`,gap:8},children:[(0,z.jsx)(at,{value:nd(a),options:[{value:`inherit`,label:i(`claude.useMainSetting`)},{value:`auto`,label:i(`dash.backendAuto`)},{value:`openai`,label:i(`dash.backendOpenAI`)},{value:`anthropic`,label:i(`dash.backendAnthropic`)}],onChange:n=>{r({...e,[t]:rd(a,n)})},label:i(`dash.sidecarBackend`),portal:!0}),(0,z.jsx)(`input`,{className:`input mono`,value:a?.model??``,onChange:n=>{r({...e,[t]:id(a,n.target.value)})},placeholder:i(`claude.sidecarModelPlaceholder`),disabled:!a,list:a?c:void 0,"aria-label":i(`dash.sidecarModel`),style:{minWidth:210},autoComplete:`off`}),a&&(0,z.jsx)(`datalist`,{id:c,children:n.map(e=>(0,z.jsx)(`option`,{value:e},e))})]})]},t)})]})}function pd({manualEnv:e}){let t=K();return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:(0,z.jsx)(Ue,{k:`claude.quickstartHint`,cmd:`ocx claude`})}),(0,z.jsx)(`pre`,{className:`mono card`,style:{padding:`10px 14px`,overflowX:`auto`,margin:0},children:`ocx claude`}),(0,z.jsxs)(`details`,{style:{margin:`10px 0 0`},children:[(0,z.jsx)(`summary`,{className:`muted text-label`,style:{cursor:`pointer`,padding:`2px 2px`},children:t(`claude.manualEnv`)}),(0,z.jsx)(`pre`,{className:`mono card text-label`,style:{padding:`10px 14px`,overflowX:`auto`,margin:`6px 0 0`},children:e})]})]})}function md({rows:e,onRowsChange:t}){let n=K();return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`p`,{className:`muted text-label`,style:{margin:`0 0 8px`},children:n(`claude.modelMapHint`)}),(0,z.jsx)(`div`,{className:`stack`,style:{gap:8},children:e.map((r,i)=>(0,z.jsxs)(`div`,{className:`row`,style:{gap:8},children:[(0,z.jsx)(`input`,{className:`input mono`,value:r.from,placeholder:n(`claude.mapFrom`),"aria-label":n(`claude.mapFrom`),onChange:n=>t(e.map((e,t)=>t===i?{...e,from:n.target.value}:e)),style:{flex:1}}),(0,z.jsx)(`span`,{className:`muted`,"aria-hidden":!0,children:`→`}),(0,z.jsx)(`input`,{className:`input mono`,value:r.to,placeholder:n(`claude.mapTo`),"aria-label":n(`claude.mapTo`),onChange:n=>t(e.map((e,t)=>t===i?{...e,to:n.target.value}:e)),style:{flex:1}}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-icon btn-sm`,onClick:()=>t(e.filter((e,t)=>t!==i)),"aria-label":n(`claude.removeMapping`),style:{color:`var(--red)`},children:(0,z.jsx)(ae,{})})]},r.id))}),(0,z.jsx)(`div`,{style:{marginTop:8},children:(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>t([...e,{id:ld(),from:``,to:``}]),children:[(0,z.jsx)(oe,{}),` `,n(`claude.addMapping`)]})})]})}var hd=`etc`;function gd(e){let t=new Map;for(let n of e){let e=/\(([^)]+)\)\s*$/.exec(n.display_name),r=e?e[1]:hd,i=t.get(r);i?i.push(n):t.set(r,[n])}return Array.from(t)}function _d({aliases:e}){let t=K();return(0,z.jsxs)(`div`,{className:`claude-aliases`,children:[(0,z.jsx)(`p`,{className:`muted text-label claude-aliases-hint`,children:t(`claude.aliasesHint`)}),e.length===0?(0,z.jsx)(`div`,{className:`muted text-label`,children:t(`claude.none`)}):(0,z.jsx)(`div`,{className:`claude-aliases-scroll`,children:gd(e).map(([e,n])=>(0,z.jsxs)(`div`,{className:`claude-aliases-group`,children:[(0,z.jsxs)(`div`,{className:`claude-aliases-group-label`,children:[e===hd?t(`claude.aliasProviderOther`):e,(0,z.jsx)(`span`,{className:`claude-aliases-group-count`,children:n.length})]}),(0,z.jsx)(`div`,{className:`claude-aliases-chips`,children:n.map(e=>(0,z.jsxs)(`span`,{className:`claude-aliases-chip`,children:[(0,z.jsx)(`code`,{className:`claude-aliases-chip-id`,children:e.id}),e.display_name?(0,z.jsx)(`span`,{className:`claude-aliases-chip-name`,children:e.display_name}):null]},e.id))})]},e))})]})}function vd({apiBase:e,active:t=!0}){let n=K(),{locale:r}=Ve(),i=Ie.find(e=>e.code===r)?.htmlLang??`en`,a=`ocx.claude-code.v1:${e}`,o=`claude-code:${e}`,s=(0,_.useMemo)(()=>Y(a),[a]),[c,l]=(0,_.useState)(()=>s?.state??null),[u,d]=(0,_.useState)(()=>s?.rows??[]),[f,p]=(0,_.useState)(!!s),[m,h]=(0,_.useState)(``),[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(`settings`),x=(0,_.useCallback)(async t=>{let r=await J(await fetch(`${e}/api/claude-code`,{signal:t}),n(`claude.loadFail`));if(!r)throw Error(n(`claude.loadFail`));let i={...r,authMode:r.authMode===`proxy`||r.authMode===`subscription`?r.authMode:`auto`,...$u(r),fastMode:r.fastMode??null,maxContextTokens:r.maxContextTokens??null,autoContext:r.autoContext!==!1,autoCompactWindow:r.autoCompactWindow??null,injectAgents:r.injectAgents!==!1,effectiveModelEnv:r.effectiveModelEnv??{}},o=Object.entries(r.modelMap??{}).map(([e,t])=>({id:ld(),from:e,to:String(t)})),s={state:i,rows:o};if(t.aborted)throw Error(`Claude Code request aborted`);return l(i),d(o),p(!0),X(a,s),s},[e,a,n]),S=us(o,[e],x,{isEmpty:()=>!1,enabled:t,initialData:s??void 0}),C=S.state,w=C.data??s,T=c??w?.state??null,E=f?u:w?.rows??u,D=(0,_.useMemo)(()=>Qu(T?.available,n(`claude.smallFastModelUnsetOption`)),[T?.available,n]),O=(0,_.useMemo)(()=>{let e=[1e5,2e5,25e4,3e5,35e4,4e5,5e5,6e5,75e4,9e5,1e6],t=T?.autoCompactWindow??null,r=t!==null&&!e.includes(t)?[...e,t].sort((e,t)=>e-t):e;return[{value:``,label:n(`claude.autoCompactDefault`)},...r.map(e=>({value:String(e),label:ud(e,i)}))]},[T?.autoCompactWindow,n,i]),k=async()=>{if(!T)return;h(``);let t={};for(let e of E)e.from.trim()&&e.to.trim()&&(t[e.from.trim()]=e.to.trim());try{await J(await fetch(`${e}/api/claude-code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:T.enabled,authMode:T.authMode,systemEnv:T.systemEnv,fastMode:T.fastMode,autoContext:T.autoContext,autoCompactWindow:T.autoCompactWindow,injectAgents:T.injectAgents,smallFastModel:T.smallFastModel,modelMap:t,webSearchSidecar:ad(T.webSearchSidecar),visionSidecar:ad(T.visionSidecar)})}),n(`claude.saveFailed`)),v(!0),h(n(`claude.saved`)),S.refresh()}catch(e){v(!1),h(e instanceof Error&&e.message?e.message:n(`claude.networkError`))}};if(C.kind===`disabled`&&!w)return null;if(C.showSkeleton&&!w)return(0,z.jsx)(fs,{label:n(`claude.loading`),rows:3});if(C.kind===`failed-cold`)return(0,z.jsxs)(`div`,{className:`claudecode-workspace-shell`,children:[(0,z.jsx)(q,{tone:`err`,children:C.error instanceof Error?C.error.message:n(`claude.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>S.refresh(),children:n(`common.retry`)})]});if(!T)return null;let A=[{id:`settings`,label:n(`claude.workspace.settings`),body:(0,z.jsx)(fd,{state:T,autoCompactOptions:O,availableModels:T.available??[],onStateChange:l})},{id:`quickstart`,label:n(`claude.quickstart`),body:(0,z.jsx)(pd,{manualEnv:td(T)})},{id:`smallFast`,label:n(`claude.smallFastModel`),body:(0,z.jsx)(cd,{value:T.smallFastModel,tierHaikuModel:T.tierModels?.haiku,options:D,onChange:e=>l({...T,smallFastModel:e})})},{id:`modelMap`,label:n(`claude.modelMap`),meta:String(E.length),body:(0,z.jsx)(md,{rows:E,onRowsChange:e=>{p(!0),d(e)}})},{id:`aliases`,label:n(`claude.aliases`),meta:String(T.aliases.length),body:(0,z.jsx)(_d,{aliases:T.aliases})}],j=A.find(e=>e.id===y)??A[0],M=y===`settings`||y===`smallFast`||y===`modelMap`;return(0,z.jsxs)(`div`,{className:`claudecode-workspace-shell`,children:[m&&(0,z.jsx)(q,{tone:g?`ok`:`err`,children:m}),C.showError&&(0,z.jsx)(q,{tone:`err`,children:n(`claude.loadFail`)}),(0,z.jsxs)(`div`,{className:`claudecode-workspace-root`,children:[(0,z.jsx)(`aside`,{className:`claudecode-workspace-rail`,"aria-label":n(`claude.pageTitle`),children:(0,z.jsx)(`div`,{className:`claudecode-workspace-rail-list`,children:A.map(e=>(0,z.jsx)(`button`,{type:`button`,className:`claudecode-workspace-rail-row${y===e.id?` claudecode-workspace-rail-row--selected`:``}`,onClick:()=>b(e.id),"aria-current":y===e.id?`true`:void 0,children:(0,z.jsx)(`span`,{className:`claudecode-workspace-rail-name`,children:e.label})},e.id))})}),(0,z.jsxs)(`section`,{className:`claudecode-workspace-main`,"aria-label":j.label,children:[(0,z.jsxs)(`div`,{className:`ccw-main-head`,children:[(0,z.jsxs)(`h3`,{className:`ccw-main-title`,children:[j.label,j.meta==null?null:(0,z.jsx)(`span`,{className:`count`,children:j.meta})]}),(0,z.jsx)(`div`,{className:`claudecode-workspace-save`,"data-visible":M?`true`:`false`,children:(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,disabled:!M,tabIndex:M?0:-1,"aria-hidden":!M,onClick:()=>{k()},children:n(`common.save`)})})]}),(0,z.jsx)(`div`,{className:`ccw-body`,children:j.body})]})]})]})}function $(e,t,n){let r=t.trim().toLowerCase(),i=(r?e.filter(e=>e.label.toLowerCase().includes(r)||e.route.toLowerCase().includes(r)):e).toSorted((e,t)=>Number(!e.available)-Number(!t.available)),a=i.slice(0,n);return{total:e.length,showSearch:e.length>4,shown:a,hidden:i.length-a.length,noMatch:e.length>0&&i.length===0}}function yd(e){return new Set(Object.keys(e))}function bd(e,t){return t!==null&&e===t}function xd(e){return e||(typeof localStorage>`u`?void 0:localStorage)}function Sd(e){return{read(t){let n=xd(t);if(!n)return null;try{let t=n.getItem(e);if(t===null)return null;let r=JSON.parse(t);return Array.isArray(r)?new Set(r.filter(e=>typeof e==`string`)):null}catch{return null}},write(t,n){let r=xd(n);if(r)try{r.setItem(e,JSON.stringify([...t]))}catch{}}}}function Cd(e,t){let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n}var wd=[`opus`,`fable`,`sonnet`,`haiku`],Td=Sd(`ocx.claudeDesktop.collapsedFamilies.v2`),Ed={opus:`claudeDesktop.family.opus`,fable:`claudeDesktop.family.fable`,sonnet:`claudeDesktop.family.sonnet`,haiku:`claudeDesktop.family.haiku`};function Dd(e){return{version:1,assignments:Object.fromEntries(Object.entries(e.assignments).map(([e,t])=>[e,{...t}])),defaults:{...e.defaults},...e.appliedFingerprint===void 0?{}:{appliedFingerprint:e.appliedFingerprint},...e.appliedAt===void 0?{}:{appliedAt:e.appliedAt}}}function Od(e){let t={...e.profile.assignments};for(let n of e.models){let e=t[n.route]??n.assignment;t[n.route]={family:wd.includes(e?.family)?e.family:`opus`,alias:typeof e?.alias==`string`?e.alias:``}}return{version:1,assignments:t,defaults:{opus:e.profile.defaults.opus??null,fable:e.profile.defaults.fable??null,sonnet:e.profile.defaults.sonnet??null,haiku:e.profile.defaults.haiku??null}}}function kd(e,t){return e&&typeof e==`object`&&`error`in e&&typeof e.error==`string`?e.error:t}function Ad(e,t){return e?e>=1048576?t(`claudeDesktop.contextM`,{n:Math.round(e/1048576)}):e>=1e6?t(`claudeDesktop.contextM`,{n:e/1e6}):t(`claudeDesktop.contextK`,{n:Math.round(e/1e3)}):null}function jd(e){return Y(e)}function Md(e){let t=jd(e);return{held:t,data:t?.data??null,profile:t?.profile??null,savedProfile:t?.profile?Dd(t.profile):null,destinations:t?.data?Object.fromEntries(t.data.models.map(e=>[e.route,t.profile.assignments[e.route]?.family??`opus`])):{}}}function Nd({apiBase:e,active:t=!0,onPortChange:n}){let{t:r,locale:i}=Ve(),a=Ie.find(e=>e.code===i)?.htmlLang,o=`ocx.claude-desktop.v1:${e}`,s=`claude-desktop:${e}`,c=(0,_.useMemo)(()=>Md(o),[o]),[l,u]=(0,_.useState)(()=>c.profile),[d,f]=(0,_.useState)(()=>c.savedProfile),[p,m]=(0,_.useState)(()=>c.destinations),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(``),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)({}),[w,T]=(0,_.useState)({}),[E,D]=(0,_.useState)(()=>Td.read()??new Set(wd)),[O,k]=(0,_.useState)({}),A=(0,_.useRef)(null),j=(0,_.useCallback)(async t=>{let n=await J(await fetch(`${e}/api/claude-desktop`,{signal:t}),r(`claudeDesktop.loadFail`));if(!n||!(`profile`in n)||!(`models`in n))throw Error(kd(n,r(`claudeDesktop.loadFail`)));let i=Od(n),a={data:n,profile:i};if(t.aborted)throw Error(`Claude Desktop request aborted`);if(u(i),f(Dd(i)),m(Object.fromEntries(n.models.map(e=>[e.route,i.assignments[e.route]?.family??`opus`]))),Td.read()===null){let e=Object.fromEntries(wd.map(e=>[e,0]));for(let t of n.models)e[i.assignments[t.route]?.family??`opus`]+=1;D(yd(e))}return X(o,a),a},[e,o,r,m,u,f]),M=us(s,[e],j,{isEmpty:()=>!1,enabled:t,initialData:c.held??void 0}),N=M.state,P=N.data??(c.data&&c.profile?{data:c.data,profile:c.profile}:null),F=P?.data??null,I=l??P?.profile??null,L=d??P?.profile??null,R=P?Object.fromEntries(P.data.models.map(e=>[e.route,P.profile.assignments[e.route]?.family??`opus`])):{},B=Object.keys(p).length>0?p:R;(0,_.useEffect)(()=>{if(n){if(typeof F?.port==`number`){n(F.port);return}N.kind===`failed-cold`&&n(null)}},[F?.port,N.kind,n]);let V=(0,_.useMemo)(()=>I!==null&&L!==null&&JSON.stringify(I)!==JSON.stringify(L),[I,L]),H=(0,_.useMemo)(()=>{let e=Object.fromEntries(wd.map(e=>[e,[]]));if(!F||!I)return e;for(let t of F.models)e[I.assignments[t.route]?.family??`opus`].push(t);return e},[F,I]),U=(0,_.useMemo)(()=>{let e={};for(let t of wd){let n=H[t].filter(e=>e.available).map(e=>e.route).sort(),r=I?.defaults[t]??null;e[t]=r&&n.includes(r)?r:n[0]??null}return e},[H,I]),W=`ocx.claude-desktop.status.v1:${e}`,ee=`claude-desktop-status:${e}`,te=Y(W),ne=us(ee,[e],async t=>{let n=await ut(await fetch(`${e}/api/claude-desktop/status`,{signal:t}));if(!n)throw Error(`Claude Desktop status unavailable`);return X(W,n),n},{isEmpty:()=>!1,pollMs:5e3,enabled:t,initialData:te??void 0}),re=ne.state,G=re.data??te??null,ie=re.showError,ae=(e,t)=>{!I||I.assignments[e]?.family===t||(u(n=>{if(!n)return n;let r=n.assignments[e];if(!r||r.family===t)return n;let i={...n.assignments,[e]:{...r,family:t}},a={...n.defaults};return a[r.family]===e&&(a[r.family]=Object.keys(i).filter(t=>t!==e&&i[t].family===r.family).sort()[0]??null),a[t]===null&&(a[t]=e),{...n,assignments:i,defaults:a}}),m(n=>({...n,[e]:t})),y(r(`claudeDesktop.moved`,{route:e,family:r(Ed[t])})))},oe=e=>{let t=Cd(E,e);Td.write(t),D(t)},se=async t=>{if(!(!I||b)){x(`save`),g(null);try{await J(await fetch(`${e}/api/claude-desktop`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({profile:I})}),r(`claudeDesktop.saveFailed`)),f(Dd(I)),t?(x(`apply`),await J(await fetch(`${e}/api/claude-desktop/apply`,{method:`POST`}),r(`claudeDesktop.applyFailed`)),g({tone:`ok`,text:r(`claudeDesktop.savedApplied`)}),y(r(`claudeDesktop.savedAppliedAnnounce`))):(g({tone:`ok`,text:r(`claudeDesktop.saved`)}),y(r(`claudeDesktop.savedAnnounce`))),ne.refresh()}catch(e){let t=e instanceof Error?e.message:r(`claudeDesktop.updateFailed`);g({tone:`err`,text:t}),y(t)}finally{x(null)}}},ce=()=>{if(!I)return;let e=URL.createObjectURL(new Blob([`${JSON.stringify(I,null,2)}\n`],{type:`application/json`})),t=document.createElement(`a`);t.href=e,t.download=`claude-desktop-profile.json`,t.click(),URL.revokeObjectURL(e),y(r(`claudeDesktop.exported`))},le=async e=>{let t=e.target.files?.[0];if(e.target.value=``,t)try{let e=JSON.parse(await t.text());if(e.version!==1||!e.assignments||!e.defaults)throw Error(r(`claudeDesktop.importExpected`));u(Od({...F,profile:e})),g({tone:`ok`,text:r(`claudeDesktop.importReady`)}),y(r(`claudeDesktop.importedAnnounce`))}catch(e){let t=e instanceof Error?e.message:r(`claudeDesktop.importInvalid`);g({tone:`err`,text:t}),y(r(`claudeDesktop.importFailed`,{error:t}))}},ue=(e,t)=>{e.preventDefault();let n=e.dataTransfer.getData(`text/plain`);n&&ae(n,t)};return N.kind===`disabled`&&!P?null:N.showSkeleton&&!P?(0,z.jsx)(fs,{label:r(`claudeDesktop.loading`),rows:4}):N.kind===`failed-cold`?(0,z.jsxs)(`div`,{className:`claude-desktop-error`,children:[(0,z.jsx)(q,{tone:`err`,children:N.error instanceof Error?N.error.message:r(`claudeDesktop.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,onClick:()=>M.refresh(),children:r(`claudeDesktop.retry`)})]}):!F||!I?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`div`,{className:`claude-desktop-toolbar`,children:(0,z.jsxs)(`div`,{className:`claude-profile-tools`,children:[(0,z.jsx)(`input`,{ref:A,type:`file`,accept:`application/json,.json`,hidden:!0,onChange:e=>void le(e)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A.current?.click(),children:r(`claudeDesktop.importJson`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:ce,children:r(`claudeDesktop.exportJson`)})]})}),(0,z.jsxs)(`div`,{className:`claude-status-bar ${ie&&!G?`not-applied`:G?G.activeProfile===!1?`not-applied`:G.stale?`stale`:G.applied?`applied`:`not-applied`:`pending`}`,"aria-busy":!G&&!ie||void 0,children:[(0,z.jsx)(`span`,{className:`claude-status-dot`}),(0,z.jsx)(`span`,{children:ie&&!G?r(`claudeDesktop.loadFail`):G?G.activeProfile===!1?r(`claudeDesktop.status.notActiveProfile`):G.stale?r(`claudeDesktop.status.stale`):G.applied?r(`claudeDesktop.status.applied`):r(`claudeDesktop.status.notApplied`):r(`claudeDesktop.loading`)}),G?.health.lastRequestAt&&(0,z.jsxs)(`span`,{className:`claude-status-health`,children:[r(`claudeDesktop.health.lastRequest`),`:`,` `,new Date(G.health.lastRequestAt).toLocaleTimeString(a)]}),G&&G.health.requestCount>0&&(0,z.jsx)(`span`,{className:`claude-status-health`,children:r(`claudeDesktop.health.stats`,{count:G.health.requestCount,errors:G.health.errorCount})})]}),(0,z.jsx)(`div`,{className:`sr-only`,"aria-live":`polite`,"aria-atomic":`true`,children:v}),h&&(0,z.jsx)(q,{tone:h.tone,children:h.text}),N.showError&&(0,z.jsx)(q,{tone:`err`,children:r(`claudeDesktop.loadFail`)}),ie&&G&&(0,z.jsx)(q,{tone:`err`,children:r(`claudeDesktop.loadFail`)}),(0,z.jsxs)(`div`,{className:`claude-profile-bar`,children:[(0,z.jsx)(`span`,{className:`claude-dirty${V?` active`:``}`,children:r(V?`claudeDesktop.unsaved`:`claudeDesktop.upToDate`)}),(0,z.jsxs)(`div`,{className:`claude-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:!V||b!==null,onClick:()=>void se(!1),children:r(b===`save`?`claudeDesktop.saving`:`common.save`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:b!==null,onClick:()=>void se(!0),children:r(b===`apply`?`claudeDesktop.applying`:b===`save`?`claudeDesktop.saving`:`claudeDesktop.saveApply`)})]})]}),F.models.length===0&&(0,z.jsx)(ot,{title:r(`claudeDesktop.emptyTitle`),children:r(`claudeDesktop.emptyHint`)}),(0,z.jsx)(`div`,{className:`ocx-group-stack`,"aria-label":r(`claudeDesktop.assignmentsLabel`),children:wd.map(e=>{let t=H[e],n=$(t,S[e]??``,w[e]??6),i=E.has(e),a=U[e];return(0,z.jsxs)(`section`,{className:`ocx-group${i?` collapsed`:``}`,"aria-labelledby":`claude-lane-${e}`,onDragOver:e=>e.preventDefault(),onDrop:t=>ue(t,e),children:[(0,z.jsxs)(`header`,{className:`ocx-group-head${i?``:` open`}`,children:[(0,z.jsx)(`h3`,{id:`claude-lane-${e}`,className:`ocx-group-heading`,children:(0,z.jsxs)(`button`,{type:`button`,className:`ocx-group-toggle`,"aria-expanded":!i,"aria-controls":`claude-lane-body-${e}`,onClick:()=>oe(e),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:14,height:14,"aria-hidden":`true`,style:{transform:i?`none`:`rotate(90deg)`}}),(0,z.jsx)(`span`,{className:`ocx-group-name`,children:r(Ed[e])}),(0,z.jsx)(`span`,{className:`ocx-group-count`,children:r(t.length===1?`claudeDesktop.modelCountOne`:`claudeDesktop.modelCountMany`,{count:t.length})}),a&&(0,z.jsx)(`code`,{className:`claude-lane-default`,title:a,children:a})]})}),t.length>0&&I.defaults[e]===null&&(0,z.jsx)(`span`,{className:`claude-default-needed`,children:r(`claudeDesktop.chooseDefault`)}),a&&a!==I.defaults[e]&&(0,z.jsx)(`span`,{className:`claude-default-needed`,title:a,children:r(`claudeDesktop.temporaryDefault`)})]}),!i&&(0,z.jsxs)(`div`,{id:`claude-lane-body-${e}`,children:[n.showSearch&&(0,z.jsx)(`input`,{className:`input claude-lane-search`,type:`search`,placeholder:r(`models.search`),"aria-label":r(`models.search`),value:S[e]??``,onChange:t=>{let n=t.target.value;C(t=>({...t,[e]:n})),T(t=>({...t,[e]:6}))}}),(0,z.jsxs)(`div`,{className:`claude-lane-models`,children:[t.length===0?(0,z.jsx)(`div`,{className:`claude-lane-empty`,children:r(`claudeDesktop.laneEmpty`)}):n.noMatch?(0,z.jsx)(`div`,{className:`claude-lane-empty`,children:r(`claudeDesktop.laneNoMatch`)}):n.shown.map(t=>{let n=I.assignments[t.route],i=Ad(t.contextWindow,r),a=B[t.route]??`opus`,o=O[t.route]??bd(t.route,U[e]);return(0,z.jsxs)(`article`,{className:`claude-model-card${o?` open`:``}`,draggable:t.available,onDragStart:e=>{e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,t.route)},children:[(0,z.jsxs)(`button`,{type:`button`,className:`claude-model-summary`,"aria-expanded":o,"aria-controls":`claude-model-body-${t.route}`,onClick:()=>k(e=>({...e,[t.route]:!o})),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:12,height:12,"aria-hidden":`true`,style:{transform:o?`rotate(90deg)`:`none`}}),(0,z.jsxs)(`span`,{className:`claude-model-names`,children:[(0,z.jsx)(`strong`,{title:t.label,children:t.label}),(0,z.jsx)(`code`,{title:t.route,children:t.route})]}),i&&(0,z.jsx)(`span`,{className:`claude-model-context`,children:i}),!i&&(0,z.jsx)(`span`,{className:`claude-model-context claude-model-context-unknown`,children:r(`claudeDesktop.contextUnknown`)}),t.supports1m===!0&&(0,z.jsx)(`span`,{className:`claude-1m-chip`,children:r(`claudeDesktop.supports1m`)}),t.effortSupported===!1&&(0,z.jsx)(`span`,{className:`claude-effort-badge off`,children:r(`claudeDesktop.effort.displayOnly`)}),t.effortSupported===!0&&(0,z.jsx)(`span`,{className:`claude-effort-badge on`,children:r(`claudeDesktop.effort.supported`)}),I.defaults[e]===t.route&&(0,z.jsx)(`span`,{className:`claude-row-default`,children:r(`claudeDesktop.defaultBadge`)}),(0,z.jsx)(`span`,{className:`badge ${t.available?`badge-green`:`badge-muted`}`,children:t.available?r(`claudeDesktop.available`):r(`claudeDesktop.unavailable`)})]}),o&&(0,z.jsxs)(`div`,{className:`claude-model-body`,id:`claude-model-body-${t.route}`,children:[U[e]===t.route&&I.defaults[e]!==t.route&&(0,z.jsx)(`span`,{className:`claude-effective-default`,children:r(`claudeDesktop.temporaryDefault`)}),(0,z.jsxs)(`div`,{className:`claude-field`,children:[(0,z.jsx)(`span`,{children:r(`claudeDesktop.alias`)}),(0,z.jsx)(`code`,{className:`claude-alias`,title:n.alias,children:n.alias})]}),(0,z.jsxs)(`label`,{className:`claude-default-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`default-${e}`,checked:I.defaults[e]===t.route,disabled:!t.available,onChange:()=>u(n=>n&&{...n,defaults:{...n.defaults,[e]:t.route}})}),r(`claudeDesktop.useAsDefault`,{family:r(Ed[e])})]}),(0,z.jsxs)(`div`,{className:`claude-move-row`,children:[(0,z.jsx)(`label`,{htmlFor:`move-${t.route}`,children:r(`claudeDesktop.moveTo`)}),(0,z.jsx)(`select`,{id:`move-${t.route}`,className:`input`,value:a,disabled:!t.available,onChange:e=>m(n=>({...n,[t.route]:e.target.value})),children:wd.map(e=>(0,z.jsx)(`option`,{value:e,children:r(Ed[e])},e))}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,disabled:!t.available||a===e,onClick:()=>ae(t.route,a),children:r(`claudeDesktop.move`)})]})]})]},t.route)}),n.hidden>0&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm claude-lane-more`,onClick:()=>T(t=>({...t,[e]:(t[e]??6)+6})),children:r(`models.showMore`,{n:n.hidden})})]})]})]},e)})})]})}function Pd(e){let t=Y(`ocx.claude-desktop.v1:${e}`);return typeof t?.data?.port==`number`?t.data.port:null}function Fd({apiBase:e}){let[t,n]=(0,_.useState)(`code`),r=K(),i=(0,_.useRef)(null),a=(0,_.useRef)(null),o=Pd(e),[s,c]=(0,_.useState)(null),l=s?.base===e?s.port:o,u=s?.base===e,d=(0,_.useCallback)(t=>{c(n=>n?.base===e&&n.port===t?n:{base:e,port:t})},[e]),f=e=>{n(e),window.requestAnimationFrame(()=>{(e===`code`?i:a).current?.focus({preventScroll:!0})})},p=e=>{e.key===`ArrowLeft`||e.key===`ArrowRight`?(e.preventDefault(),f(t===`code`?`desktop`:`code`)):e.key===`Home`?(e.preventDefault(),f(`code`)):e.key===`End`&&(e.preventDefault(),f(`desktop`))};return(0,z.jsxs)(`section`,{className:`claude-page`,children:[(0,z.jsxs)(`div`,{className:`claude-page-intro`,children:[(0,z.jsx)(`div`,{className:`page-head`,children:(0,z.jsx)(`h2`,{children:r(t===`code`?`claude.pageTitle`:`claudeDesktop.title`)})}),t===`code`?(0,z.jsx)(`p`,{className:`page-sub`,children:r(`claude.subtitle`)}):(0,z.jsx)(`p`,{className:`page-sub`,children:l==null?r(u?`claudeDesktop.loadFail`:`claudeDesktop.loading`):r(`claudeDesktop.subtitle`,{port:l})})]}),(0,z.jsxs)(`div`,{className:`claude-tabs`,role:`tablist`,"aria-label":r(`claude.tabsLabel`),children:[(0,z.jsx)(`button`,{type:`button`,role:`tab`,ref:i,"aria-selected":t===`code`,"aria-controls":`claude-code-panel`,id:`claude-code-tab`,className:t===`code`?`active`:``,tabIndex:t===`code`?0:-1,onKeyDown:p,onClick:()=>f(`code`),children:r(`claude.tabCode`)}),(0,z.jsx)(`button`,{type:`button`,role:`tab`,ref:a,"aria-selected":t===`desktop`,"aria-controls":`claude-desktop-panel`,id:`claude-desktop-tab`,className:t===`desktop`?`active`:``,tabIndex:t===`desktop`?0:-1,onKeyDown:p,onClick:()=>f(`desktop`),children:r(`claude.tabDesktop`)})]}),(0,z.jsx)(`div`,{id:`claude-code-panel`,role:`tabpanel`,"aria-labelledby":`claude-code-tab`,hidden:t!==`code`,children:(0,z.jsx)(vd,{apiBase:e,active:t===`code`},e)}),(0,z.jsx)(`div`,{id:`claude-desktop-panel`,role:`tabpanel`,"aria-labelledby":`claude-desktop-tab`,hidden:t!==`desktop`,children:(0,z.jsx)(Nd,{apiBase:e,active:t===`desktop`,onPortChange:d},e)})]})}function Id(e,t,n,r){let i=e.filter(e=>r===`native`===e.native).map(e=>({...e,alias:t.get(e.id)??null,enabled:!n.has(e.id)})).toSorted((e,t)=>Number(!e.enabled)-Number(!t.enabled));return{rows:i,total:i.length,enabled:i.filter(e=>e.enabled).length}}var Ld=Sd(`ocx.grok.collapsedGroups.v2`),Rd=[{id:`native`,tkey:`grok.groupNative`},{id:`routed`,tkey:`grok.groupRouted`}],zd=new Set(Rd.map(e=>e.id));function Bd(e,t){return e?e>=1048576?t(`claudeDesktop.contextM`,{n:Math.round(e/1048576)}):e>=1e6?t(`claudeDesktop.contextM`,{n:e/1e6}):t(`claudeDesktop.contextK`,{n:Math.round(e/1e3)}):`—`}function Vd({apiBase:e}){let t=K(),n=`ocx.grok.status.v1:${e}`,r=Y(n),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(()=>Ld.read()??new Set(zd)),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)(null),[f,p]=(0,_.useState)(``),m=(0,_.useCallback)(async()=>{let r=await J(await fetch(`${e}/api/grok`),t(`grok.loadFail`));if(!r)throw Error(t(`grok.loadFail`));let i={...r,candidates:r.candidates??[],excluded:r.excluded??[]};return X(n,i),i},[e,n,t]),h=`grok-status:${e}`,g=us(h,[e],m,{isEmpty:()=>!1,initialData:r??void 0}),{state:v}=g,y=g.refresh,b=v.data??r,x=(0,_.useMemo)(()=>new Set(b?.excluded??[]),[b]),S=i??x,C=(0,_.useMemo)(()=>i!==null&&(i.size!==x.size||[...i].some(e=>!x.has(e))),[i,x]),w=(0,_.useMemo)(()=>new Map((b?.models??[]).map(e=>[e.id,e.alias])),[b]),T=e=>{let t=Cd(o,e);Ld.write(t),s(t)},E=e=>{let t=e?new Set(Rd.map(e=>e.id)):new Set;Ld.write(t),s(t)},D=(e,t)=>{a(n=>{let r=new Set(n??x);return t?r.delete(e):r.add(e),r})},O=async r=>{if(!c){l(`save`),d(null);try{await J(await fetch(`${e}/api/grok/selection`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({excluded:[...S]})}),t(`grok.saveFailed`));let i=[...S];if(b&&L(h,{...b,excluded:i}),a(null),r){l(`apply`);let n=await fetch(`${e}/api/grok/apply`,{method:`POST`});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.message??e.error??t(`grok.applyFailed`))}let r=await n.json().catch(()=>({}));r.skippedReason?(d({tone:`err`,text:r.message??t(`grok.applySkipped`)}),p(r.message??t(`grok.applySkipped`))):(d({tone:`ok`,text:t(`grok.savedApplied`)}),p(t(`grok.savedApplied`))),await y()}else d({tone:`ok`,text:t(`grok.saved`)}),p(t(`grok.saved`)),b&&X(n,{...b,excluded:i})}catch(e){let n=e instanceof Error?e.message:t(`grok.saveFailed`);d({tone:`err`,text:n}),p(n)}finally{l(null)}}};return v.showSkeleton&&!b?(0,z.jsx)(`section`,{className:`grok-page`,children:(0,z.jsx)(fs,{label:t(`grok.loading`),rows:4})}):v.kind===`failed-cold`?(0,z.jsxs)(`section`,{className:`grok-page`,children:[(0,z.jsx)(`div`,{className:`alert alert-err`,role:`alert`,children:v.error instanceof Error?v.error.message:t(`grok.loadFail`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>y(),children:t(`common.retry`)})]}):(0,z.jsxs)(`section`,{className:`grok-page`,"aria-busy":v.refreshing||void 0,children:[(0,z.jsx)(`h2`,{className:`page-title`,children:t(`grok.title`)}),(0,z.jsx)(`p`,{className:`page-sub`,children:t(`grok.subtitle`)}),(0,z.jsx)(`div`,{className:`sr-only`,"aria-live":`polite`,"aria-atomic":`true`,children:f}),u&&(0,z.jsx)(q,{tone:u.tone,children:u.text}),v.showError&&(0,z.jsx)(q,{tone:`err`,children:t(`grok.loadFail`)}),b&&b.candidates.length>0&&(0,z.jsxs)(`div`,{className:`claude-profile-bar`,children:[(0,z.jsx)(`span`,{className:`claude-dirty${C?` active`:``}`,children:t(C?`grok.unsaved`:`grok.upToDate`)}),(0,z.jsxs)(`div`,{className:`claude-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:!C||c!==null,onClick:()=>void O(!1),children:t(c===`save`?`grok.saving`:`common.save`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:!C||c!==null,onClick:()=>void O(!0),children:t(c===`apply`?`grok.applying`:c===`save`?`grok.saving`:`grok.saveApply`)})]})]}),b?.present?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`div`,{className:`grok-endpoint`,children:[(0,z.jsx)(`span`,{children:t(`grok.endpoint`)}),(0,z.jsx)(`code`,{children:b.baseUrl??`—`})]}),(0,z.jsx)(`p`,{className:`page-sub`,children:(0,z.jsx)(`code`,{children:b.configPath})})]}):(0,z.jsxs)(ot,{title:t(`grok.notConfiguredTitle`),children:[t(`grok.notConfiguredHint`),(0,z.jsx)(`br`,{}),(0,z.jsx)(`code`,{children:b?.configPath})]}),b&&b.candidates.length>0&&(0,z.jsxs)(`div`,{className:`ocx-group-stack`,children:[(0,z.jsxs)(`div`,{className:`row`,style:{gap:6,margin:`2px 0 10px`},children:[(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm text-caption`,onClick:()=>E(!0),disabled:c!==null,children:[(0,z.jsx)(_e,{width:12,height:12,"aria-hidden":`true`}),` `,t(`models.collapseAll`)]}),(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm text-caption`,onClick:()=>E(!1),disabled:c!==null,children:[(0,z.jsx)(_e,{width:12,height:12,"aria-hidden":`true`,style:{transform:`rotate(90deg)`}}),` `,t(`models.expandAll`)]})]}),Rd.map(e=>{let n=Id(b.candidates,w,S,e.id);if(n.total===0)return null;let r=o.has(e.id);return(0,z.jsxs)(`section`,{className:`ocx-group${r?` collapsed`:``}`,"aria-labelledby":`grok-group-${e.id}`,children:[(0,z.jsx)(`header`,{className:`ocx-group-head${r?``:` open`}`,children:(0,z.jsx)(`h3`,{id:`grok-group-${e.id}`,className:`ocx-group-heading`,children:(0,z.jsxs)(`button`,{type:`button`,className:`ocx-group-toggle`,"aria-expanded":!r,"aria-controls":`grok-group-body-${e.id}`,onClick:()=>T(e.id),children:[(0,z.jsx)(_e,{className:`ocx-chevron`,width:14,height:14,"aria-hidden":`true`,style:{transform:r?`none`:`rotate(90deg)`}}),(0,z.jsx)(`span`,{className:`ocx-group-name`,children:t(e.tkey)}),(0,z.jsx)(`span`,{className:`ocx-group-count`,children:t(`grok.enabledCount`,{on:n.enabled,total:n.total})})]})})}),!r&&(0,z.jsx)(`div`,{id:`grok-group-body-${e.id}`,className:`grok-model-list`,children:n.rows.map(e=>(0,z.jsxs)(`div`,{className:`grok-model-row`,children:[(0,z.jsx)(it,{on:e.enabled,onClick:()=>D(e.id,!e.enabled),disabled:c!==null,label:t(`grok.toggleModel`,{id:e.id})}),(0,z.jsxs)(`span`,{className:`grok-model-names`,children:[(0,z.jsx)(`strong`,{title:e.id,children:e.id}),(0,z.jsx)(`code`,{title:e.alias??void 0,children:e.alias??`—`})]}),(0,z.jsx)(`span`,{className:`claude-model-context`,children:Bd(e.contextWindow,t)})]},e.id))})]},e.id)})]})]})}function Hd(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.supported==`boolean`&&typeof t.installed==`boolean`&&typeof t.running==`boolean`&&typeof t.stale==`boolean`&&typeof t.summary==`string`}var Ud={native:`startup.status.native`,protected:`startup.status.protected`,"at-risk":`startup.status.atRisk`},Wd={native:`startup.summary.native`,protected:`startup.summary.protected`,"at-risk":`startup.summary.atRisk`},Gd={service:`startup.protection.service`,shim:`startup.protection.shim`,none:`startup.protection.none`};function Kd({ok:e,yes:t,no:n}){return(0,z.jsx)(`span`,{className:`badge ${e?`badge-green`:`badge-amber`}`,children:e?t:n})}function qd({failed:e,data:t}){let{t:n}=Ve(),r=e?`startup-hero--risk`:t.status===`protected`?`startup-hero--safe`:t.status===`at-risk`?`startup-hero--risk`:`startup-hero--native`,i=e||t.status===`at-risk`?de:ie,a=t.routingKind===`opencodex-local`?`startup.routing.proxy`:t.routingKind===`custom-local`?`startup.routing.customLocal`:t.routingKind===`custom-remote`?`startup.routing.customRemote`:t.routingKind===`unknown`?`startup.routing.unknown`:`startup.routing.native`;return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`section`,{className:`panel startup-hero ${r}`,"aria-live":`polite`,children:[(0,z.jsx)(`div`,{className:`startup-hero-icon`,children:(0,z.jsx)(i,{})}),(0,z.jsxs)(`div`,{className:`startup-hero-copy`,children:[(0,z.jsx)(`span`,{className:`badge ${e||t.status===`at-risk`?`badge-amber`:`badge-green`}`,children:n(e?`startup.status.atRisk`:Ud[t.status])}),(0,z.jsx)(`h3`,{children:n(e?`startup.error`:Wd[t.status])}),(0,z.jsx)(`p`,{children:e?n(`startup.staleData`):t.status===`at-risk`?n(cn(t)):n(`startup.safeDetail`)})]})]}),(0,z.jsxs)(`div`,{className:`startup-state-grid`,children:[(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.routing`)}),(0,z.jsx)(`div`,{className:`value`,children:n(a)})]}),(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.restartProtection`)}),(0,z.jsx)(`div`,{className:`value`,children:n(Gd[t.protection])})]}),(0,z.jsxs)(`section`,{className:`stat`,children:[(0,z.jsx)(`div`,{className:`label`,children:n(`startup.preference`)}),(0,z.jsx)(`div`,{className:`value`,children:n(t.autostartEnabled?`startup.enabled`:`startup.disabled`)})]})]})]})}function Jd({data:e,failed:t,loading:n=!1,installBusy:r,installResult:i,onInstall:a}){let{t:o}=Ve(),s=e.serviceSupported&&e.serviceInstalled&&e.serviceStale&&!e.serviceConflict,c=e.shimInstalled&&!e.shimHealthy,l=r!==null||t||n;return(0,z.jsxs)(`section`,{className:`panel startup-details`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:o(`startup.details`)}),(0,z.jsx)(`span`,{className:`muted mono`,children:e.platform})]}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:o(`startup.service`)}),(0,z.jsx)(`span`,{children:o(`startup.serviceHint`)})]}),(0,z.jsxs)(`div`,{className:`startup-detail-actions`,children:[(0,z.jsx)(Kd,{ok:e.serviceViable,yes:o(`startup.viable`),no:o(e.serviceConflict?`startup.conflict`:e.serviceStale?`startup.stale`:e.serviceInstalled?`startup.unhealthy`:e.serviceSupported?`startup.notInstalled`:`startup.unsupported`)}),e.serviceSupported&&!e.serviceInstalled&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.service`)} - ${o(`startup.install`)}`,disabled:l,onClick:()=>a(`install-service`),children:o(r===`install-service`?`startup.installing`:`startup.install`)}),s&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.service`)} - ${o(`startup.repair`)}`,disabled:l,onClick:()=>a(`install-service`,{repair:!0}),children:o(r===`install-service`?`startup.repairing`:`startup.repair`)})]})]}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:o(`startup.shim`)}),(0,z.jsx)(`span`,{children:o(`startup.shimHint`)})]}),(0,z.jsxs)(`div`,{className:`startup-detail-actions`,children:[(0,z.jsx)(Kd,{ok:e.shimHealthy&&e.autostartEnabled,yes:o(e.shimCoverage===`cli-only`?`startup.cliOnly`:`startup.healthy`),no:o(e.shimInstalled?e.shimHealthy&&!e.autostartEnabled?`startup.installedDisabled`:`startup.stale`:`startup.notInstalled`)}),!e.shimInstalled&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.shim`)} - ${o(`startup.install`)}`,disabled:l,onClick:()=>a(`install-shim`),children:o(r===`install-shim`?`startup.installing`:`startup.install`)}),c&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary btn-sm`,"aria-label":`${o(`startup.shim`)} - ${o(`startup.repair`)}`,disabled:l,onClick:()=>a(`install-shim`,{repair:!0}),children:o(r===`install-shim`?`startup.repairing`:`startup.repair`)})]})]}),i&&(0,z.jsx)(`div`,{className:`notice ${i.kind===`success`?`notice-ok`:`notice-warn`} startup-action-notice`,role:`status`,"aria-live":`polite`,children:i.kind===`success`?i.action===`install-service`?o(i.repair?`startup.serviceRepaired`:`startup.serviceInstalled`):o(i.repair?`startup.shimRepaired`:`startup.shimInstalled`):`${o(`startup.installFailed`)} ${i.detail??``}`})]})}function Yd({tray:e,trayLoading:t,trayError:n,trayBusy:r,onTrayAction:i}){let{t:a}=Ve();return(0,z.jsxs)(`section`,{className:`panel startup-actions`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:a(`startup.tray.title`)}),(0,z.jsx)(ye,{})]}),(0,z.jsx)(`p`,{className:`muted`,children:a(`startup.tray.hint`)}),(0,z.jsxs)(`div`,{className:`startup-detail-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:a(`startup.tray.login`)}),(0,z.jsx)(`span`,{children:a(`startup.tray.notProtection`)})]}),t||n||!e?(0,z.jsx)(`span`,{className:`badge badge-amber`,children:a(t?`startup.tray.loading`:`startup.tray.unavailable`)}):(0,z.jsx)(Kd,{ok:e.running&&!e.stale,yes:a(`startup.tray.running`),no:a(e.stale?`startup.tray.stale`:e.installed?`startup.tray.stopped`:`startup.tray.notInstalled`)})]}),(0,z.jsxs)(`div`,{className:`startup-tray-buttons`,children:[!t&&!n&&e&&!e.installed&&!e.stale&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:r,onClick:()=>i(`install`),children:a(`startup.tray.install`)}),!t&&!n&&e?.installed&&!e.stale&&!e.running&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,disabled:r,onClick:()=>i(`start`),children:a(`startup.tray.start`)}),!t&&!n&&e?.running&&!e.stale&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,disabled:r,onClick:()=>i(`stop`),children:a(`startup.tray.stop`)}),!t&&!n&&e&&(e.installed||e.stale)&&(0,z.jsx)(`button`,{type:`button`,className:`btn btn-danger`,disabled:r,onClick:()=>{window.confirm(a(`startup.tray.uninstall`))&&i(`uninstall`)},children:a(`startup.tray.uninstall`)})]}),(n||e?.stale)&&(0,z.jsx)(`div`,{className:`notice notice-warn startup-tray-error`,role:`alert`,children:a(`startup.tray.error`)})]})}function Xd({data:e,copied:t,onCopy:n}){let{t:r}=Ve();return(0,z.jsxs)(`section`,{className:`panel startup-actions`,children:[(0,z.jsxs)(`div`,{className:`panel-head`,children:[(0,z.jsx)(`h3`,{className:`panel-title`,children:r(`startup.recovery`)}),(0,z.jsx)(ne,{})]}),(0,z.jsx)(`p`,{className:`muted`,children:r(`startup.recoveryHint`)}),(0,z.jsxs)(`div`,{className:`startup-command-list`,children:[e.serviceSupported&&(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.service`)}),(0,z.jsx)(`code`,{children:e.commands.installService})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.installService),children:t===e.commands.installService?r(`startup.copied`):r(`startup.copy`)})]}),(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.shim`)}),(0,z.jsx)(`code`,{children:e.commands.installShim})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.installShim),children:t===e.commands.installShim?r(`startup.copied`):r(`startup.copy`)})]}),(0,z.jsxs)(`div`,{className:`startup-command-row`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`strong`,{children:r(`startup.command.native`)}),(0,z.jsx)(`code`,{children:e.commands.restoreNative})]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>n(e.commands.restoreNative),children:t===e.commands.restoreNative?r(`startup.copied`):r(`startup.copy`)})]})]}),e.status===`at-risk`&&(0,z.jsxs)(`div`,{className:`notice notice-warn startup-action-notice`,role:`alert`,children:[(0,z.jsx)(ye,{}),` `,r(`startup.recommended`,{cmd:e.recommendedCommand??e.commands.installService})]})]})}var Zd=`ocx.startup.page.v1:`;function Qd(e,t){let n=t===`win32`?`; `:` && `;return e.join(n)}function $d(e,t,n){if(!e)return{warning:null,fix:null};let r=!!e.catalogClamp?.active,i=!!e.newerAvailable,a=(r?e.catalogClamp?.runtimeVersion:e.version)??e.version??`unknown`,o=(e.catalogClamp?.removedEfforts??[]).join(`, `),s=Qd([`ocx doctor --fix-codex-runtime`,`ocx sync`],n);return r?{warning:o?t(`startup.codexRuntime.clampHiddenWithEfforts`,{version:a,efforts:o}):t(`startup.codexRuntime.clampHidden`,{version:a}),fix:i?s:`ocx sync`}:i?{warning:t(`startup.codexRuntime.olderBinary`,{version:a}),fix:s}:{warning:null,fix:null}}function ef({apiBase:e}){let{t}=Ve(),n=`${Zd}${e}`,r=(0,_.useMemo)(()=>Y(n),[n]),i=`startup-page:${e}`,[a,o]=(0,_.useState)(null),[s,c]=(0,_.useState)(()=>r?.tray??null),[l,u]=(0,_.useState)(()=>!r?.data),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(null),[b,x]=(0,_.useState)(()=>r?.warning??null),[S,C]=(0,_.useState)(()=>r?.fix??null),[w,T]=(0,_.useState)(()=>!r?.data),E=(0,_.useRef)(!!r?.data),D=(0,_.useCallback)(async r=>{let i=E.current;i||(u(!0),T(!0));try{let i=fetch(`${e}/api/settings`,{signal:r}).then(async e=>e.ok?await e.json():null).catch(()=>null),a=await fetch(`${e}/api/startup-health`,{signal:r});if(!a.ok)throw Error(`fetch failed`);let o=await a.json();E.current=!0;let s=Y(n);X(n,{data:o,warning:s?.warning??null,fix:s?.fix??null,tray:s?.tray??null});let l=o.platform===`win32`?fetch(`${e}/api/windows-tray`,{signal:r}).then(async e=>{if(!e.ok)throw Error(`tray status failed`);let t=await e.json();if(!Hd(t))throw Error(`invalid tray status`);return{tray:t,error:!1}}).catch(()=>({tray:null,error:!0})):Promise.resolve({tray:null,error:!1});return Promise.all([i,l]).then(([e,i])=>{if(r.aborted)return;let a=o.platform===`win32`?i.tray:null;if(o.platform===`win32`?(c(a),m(i.error)):(c(null),m(!1)),u(!1),T(!1),e){let r=$d(e.codexRuntime,t,o.platform);x(r.warning),C(r.fix),X(n,{data:o,warning:r.warning,fix:r.fix,tray:a});return}let s=Y(n);X(n,{data:o,warning:s?.warning??null,fix:s?.fix??null,tray:a})}),o}catch(e){throw r.aborted?e:(i||(c(null),m(!0),x(null),C(null)),T(!1),u(!1),e)}},[e,n,t]),O=us(i,[e],D,{isEmpty:()=>!1,initialData:r?.data??void 0}),k=O.state,A=O.refresh,j=k.data??r?.data??null,M=k.refreshing,N=!!j?.diagnosticStale||k.showError;(0,_.useEffect)(()=>{if(!j?.diagnosticStale)return;let e=window.setTimeout(A,2e3);return()=>window.clearTimeout(e)},[j,A]);let P=async e=>{try{await navigator.clipboard.writeText(e),o(e),window.setTimeout(()=>o(t=>t===e?null:t),1600)}catch{o(null)}},F=async t=>{f(!0),m(!1);try{let n=await fetch(`${e}/api/windows-tray`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:t})});if(!n.ok)throw Error(`tray action failed`);let r=await n.json();if(!Hd(r.status))throw Error(`invalid tray action status`);c(r.status),m(!1)}catch{c(null),m(!0)}finally{f(!1)}},I=async(t,n)=>{g(t),y(null);try{let r=await fetch(`${e}/api/startup-action`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:t,repair:n?.repair===!0})});if(!r.ok){let e=await r.json().catch(()=>null);throw Error(typeof e?.error==`string`?e.error:`installation failed`)}y({kind:`success`,action:t,repair:n?.repair===!0}),A()}catch(e){y({kind:`error`,action:t,repair:n?.repair===!0,detail:e instanceof Error?e.message:String(e)})}finally{g(null)}};return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`div`,{className:`page-head`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`h2`,{children:t(`startup.title`)}),(0,z.jsx)(`p`,{className:`page-sub startup-page-sub`,children:t(`startup.subtitle`)})]}),(0,z.jsxs)(`div`,{className:`startup-page-head-actions`,children:[(0,z.jsx)(`a`,{className:`btn btn-ghost btn-sm`,href:`#dashboard`,children:t(`startup.backToDashboard`)}),(0,z.jsxs)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A(),disabled:M,children:[(0,z.jsx)(se,{}),` `,t(`startup.refresh`)]})]})]}),k.showSkeleton&&!j?(0,z.jsx)(fs,{label:t(`startup.loading`),rows:5}):k.kind===`failed-cold`?(0,z.jsxs)(`div`,{className:`startup-page-notice`,children:[(0,z.jsx)(q,{tone:`err`,children:k.error instanceof Error?k.error.message:t(`startup.error`)}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>A(),children:t(`common.retry`)})]}):j?(0,z.jsxs)(z.Fragment,{children:[k.showError&&(0,z.jsx)(q,{tone:`err`,children:t(`startup.error`)}),N&&(0,z.jsx)(`div`,{className:`notice notice-warn startup-page-notice`,role:`alert`,children:t(`startup.staleData`)}),(w||b)&&(0,z.jsx)(`div`,{className:`startup-runtime-notice-slot${w&&!b?` startup-runtime-notice-slot--pending`:``}`,"aria-hidden":w&&!b?!0:void 0,children:b&&(0,z.jsxs)(`div`,{className:`notice notice-warn startup-page-notice startup-runtime-notice`,role:`status`,children:[(0,z.jsx)(`p`,{className:`startup-runtime-notice__text`,children:b}),S&&(0,z.jsxs)(`div`,{className:`startup-runtime-notice__fix`,children:[(0,z.jsx)(`code`,{children:S}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:()=>void P(S),children:t(a===S?`startup.copied`:`startup.copy`)})]})]})}),(0,z.jsx)(qd,{failed:N,data:j}),(0,z.jsx)(Jd,{data:j,failed:N,loading:M,installBusy:h,installResult:v,onInstall:(e,t)=>{I(e,t)}}),j.platform===`win32`&&(0,z.jsx)(Yd,{tray:s,trayLoading:l,trayError:p,trayBusy:d,onTrayAction:e=>{F(e)}}),(0,z.jsx)(Xd,{data:j,copied:a,onCopy:e=>{P(e)}})]}):null]})}var tf=class extends _.Component{state={error:null};static getDerivedStateFromError(e){return{error:e instanceof Error?e:Error(String(e))}}reload=()=>{this.setState({error:null})};render(){return this.state.error?(0,z.jsxs)(`section`,{className:`card`,role:`alert`,style:{maxWidth:720,padding:`var(--space-6)`},children:[(0,z.jsxs)(`h2`,{style:{margin:`0 0 var(--space-2)`,fontSize:`var(--text-title)`},children:[this.props.pageName,`: `,this.props.title]}),(0,z.jsx)(`p`,{className:`muted`,style:{margin:`0 0 var(--space-4)`},children:this.props.message}),(0,z.jsxs)(`p`,{style:{margin:`0 0 var(--space-5)`,overflowWrap:`anywhere`},children:[(0,z.jsxs)(`strong`,{children:[this.props.detailsLabel,`:`]}),` `,this.state.error.message]}),(0,z.jsx)(`button`,{type:`button`,className:`btn btn-primary`,onClick:this.reload,children:this.props.reloadLabel})]}):this.props.children}},nf=5*6e4,rf=10*6e4,af=`https://github.com/lidge-jun/opencodex`;async function of(e,t){let n=await fetch(e,{signal:t});return n.ok?await n.json():null}function sf({apiBase:e,onOpenUpdate:t}){let n=K(),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(null),s=I(`sidebar-star:${e}`,[e],t=>of(`${e}/api/github/star`,t),{pollMs:nf}),c=I(`sidebar-update-badge:${e}`,[e],t=>of(`${e}/api/update/badge`,t),{pollMs:rf}),l=s.data?.state??null,u=a!==null&&a.basedOn===l?a.state:l??`not-starred`,d=s.data?.url??af,f=u===`starred`,p=c.data,m=p?.updateAvailable===!0,h=p?.latestVersion??null,g=()=>window.open(d,`_blank`,`noopener,noreferrer`),v=async()=>{if(!(f||r)){if(u===`unauthenticated`){g();return}i(!0);try{let t=await fetch(`${e}/api/github/star`,{method:`POST`}),n=t.ok?await t.json():null;if(n?.ok===!0){o({state:`starred`,basedOn:l});return}n?.state&&o({state:n.state,basedOn:l}),g()}catch{g()}finally{i(!1),s.refresh()}}},y=n(f?`sidebar.starred`:u===`unauthenticated`?`sidebar.starUnauthenticated`:`sidebar.star`),b=m&&h?n(`sidebar.updateAvailable`,{version:h}):n(`sidebar.checkUpdate`);return(0,z.jsxs)(`div`,{className:`sidebar-github-row`,children:[(0,z.jsxs)(`a`,{className:`sidebar-link sidebar-github-link`,href:d,target:`_blank`,rel:`noreferrer`,children:[(0,z.jsx)(ve,{}),` `,n(`common.github`)]}),(0,z.jsxs)(`div`,{className:`sidebar-github-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`sidebar-orb${f?` sidebar-orb--starred`:``}`,onClick:()=>{v()},disabled:r||f,"aria-label":y,"aria-pressed":f,title:y,children:(0,z.jsx)(Me,{"aria-hidden":`true`,...f?{fill:`currentColor`}:{}})}),(0,z.jsxs)(`button`,{type:`button`,className:`sidebar-orb${m?` sidebar-orb--update`:``}`,onClick:t,"aria-label":b,title:b,children:[(0,z.jsx)(ge,{"aria-hidden":`true`}),m&&(0,z.jsx)(`span`,{className:`sidebar-orb-dot`,"aria-hidden":`true`})]})]})]})}var cf=!1,lf=null,uf=null,df=!1,ff=`/`;function pf(e){try{let t=e instanceof Request?e.url:String(e),n=new URL(t,window.location.href);return n.origin===window.location.origin?n.pathname.startsWith(`/api/`):!1}catch{return!1}}var mf=`opencodex-api-token`,hf=null,gf=null,_f=null;function vf(){return hf}function yf(e){hf=e}function bf(){hf=null,gf=null,_f=null}function xf(e){let t=document.querySelector(`meta[name="${e}"]`),n=t?.content.trim()||null;return t?.remove(),n}function Sf(){wf(xf(`opencodex-session-token`),xf(`opencodex-session-csrf`),xf(`opencodex-session-origin`))}function Cf(e){e!=null&&vf()===e&&bf()}function wf(e,t,n){return!e?.startsWith(`ocx_session_`)||!t||n!==window.location.origin?!1:(hf=e,gf=t,_f=n,!0)}function Tf(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname="([^"]+)"/i)?.[1]===t)return n.match(/\bcontent="([^"]*)"/i)?.[1]?.trim()||null;return null}async function Ef(){if(!uf)return null;try{let e=await uf(ff,{cache:`no-store`});if(!e.ok)return null;let t=await e.text();return wf(Tf(t,`opencodex-session-token`),Tf(t,`opencodex-session-csrf`),Tf(t,`opencodex-session-origin`))?vf():null}catch{return null}}function Df(){try{sessionStorage.removeItem(mf)}catch{}}function Of(e,t,n){let r=new Headers(t?.headers??(e instanceof Request?e.headers:void 0));if(r.set(`X-OpenCodex-API-Key`,n),_f&&gf&&n.startsWith(`ocx_session_`)){r.set(`X-OpenCodex-GUI-Origin`,_f);let n=(t?.method??(e instanceof Request?e.method:`GET`)).toUpperCase();n!==`GET`&&n!==`HEAD`&&r.set(`X-OpenCodex-CSRF-Token`,gf)}return e instanceof Request?[new Request(e,{headers:r}),t?{...t,headers:r}:void 0]:[e,{...t,headers:r}]}async function kf(e){return df?null:lf||(lf=(async()=>{if(df)return null;let t=vf();if(t&&t!==e)return t;let n=await Ef();if(n)return n;let r=window.prompt(`OpenCodex admin token (OPENCODEX_ADMIN_AUTH_TOKEN)`)?.trim()||null;return r?(yf(r),r):(df=!0,null)})().finally(()=>{lf=null}),lf)}function Af(){if(cf)return;cf=!0,Df(),Sf();let e=window.fetch.bind(window);uf=e,window.fetch=async(t,n)=>{if(!pf(t))return e(t,n);let r=vf(),[i,a]=r?Of(t,n,r):[t,n],o=await e(i,a);if(o.status!==401)return o;let s=vf();if(s&&s!==r){let[r,i]=Of(t,n,s),a=await e(r,i);if(a.status!==401)return a;Cf(s)}else Cf(r);let c=await kf(r);if(!c)return o;let[l,u]=Of(t,n,c),d=await e(l,u);return d.status===401&&Cf(c),d}}var jf=new Set([`dashboard`,`startup`,`providers`,`models`,`combos`,`subagents`,`logs`,`usage`,`storage`,`codex-auth`,`api`,`claude`,`grok`]);function Mf(e){let t=We(e??(typeof window<`u`?window.location.hash:``)).split(`/`)[0];return t===`debug`?`logs`:jf.has(t)?t:`dashboard`}var Nf=[`dashboard/providers`,`dashboard/models`];function Pf(e,t){return e===t||t===`logs`&&e===`logs/debug`||t===`dashboard`&&(e===`dashboard/update`||Nf.includes(e))}function Ff(e){let t=Mf(e);return e===`debug`||e.startsWith(`debug/`)?{page:`logs`,replaceTo:`logs/debug`}:e===`providers/workspace`?{page:`providers`,replaceTo:`providers`}:Pf(e,t)?{page:t,replaceTo:null}:{page:t,replaceTo:t}}var If=[`ocx-global-view`,`ocx-view`,`ocx-providers-view`,`ocx-subagents-view`,`ocx-storage-view`,`ocx-codexauth-view`,`ocx-apikeys-view`,`ocx-claudecode-view`,`ocx-usage-view`,`ocx-logs-view`,`ocx-models-view`,`ocx-dashboard-view`];function Lf(){try{for(let e of If)localStorage.removeItem(e)}catch{}}function Rf(){let[e,t]=(0,_.useState)(Mf);(0,_.useEffect)(()=>{Lf()},[]);let n=(0,_.useCallback)(e=>{let n=Ff(e);n.replaceTo&&Ge(n.replaceTo),t(n.page)},[]);return(0,_.useEffect)(()=>{let e=()=>{n(We(window.location.hash))};return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[n]),(0,_.useEffect)(()=>{let t=We(window.location.hash);if(t===`debug`||t.startsWith(`debug/`)){Ge(`logs/debug`);return}if(t===`providers/workspace`){Ge(`providers`);return}Pf(t,e)||Ge(e)},[e]),{page:e,setPageState:t,navigateToPage:(e,n)=>{Ke(n?`${e}/${n}`:e),t(e)}}}var zf=15e3;function Bf(e,t,n){return typeof e?.message==`string`&&e.message.trim()?e.message:typeof e?.error==`string`&&e.error.trim()?e.error:n(t)}function Vf(e){return(e instanceof DOMException||e instanceof Error)&&e.name===`AbortError`}async function Hf(e,t={}){let{fetchFn:n=fetch,timeoutMs:r=zf,formatFailure:i=e=>`Failed to stop proxy (HTTP ${e}).`}=t,a;try{a=await n(`${e}/api/stop`,{method:`POST`,signal:AbortSignal.timeout(r)})}catch(e){return Vf(e),{accepted:!0}}let o=await a.json().catch(()=>null);return!a.ok||o?.success===!1?{accepted:!1,message:Bf(o,a.status,i)}:{accepted:!0}}Af();var Uf={dashboard:`nav.dashboard`,startup:`nav.startup`,providers:`nav.providers`,models:`nav.models`,combos:`nav.combos`,subagents:`nav.subagents`,logs:`nav.logs`,usage:`nav.usage`,storage:`nav.storage`,"codex-auth":`nav.codexAuth`,api:`nav.api`,claude:`nav.claude`,grok:`nav.grok`},Wf=``,Gf=`ocx-theme`,Kf=[{id:`dashboard`,tkey:`nav.dashboard`,Icon:V},{id:`codex-auth`,tkey:`nav.codexAuth`,Icon:xe},{id:`providers`,tkey:`nav.providers`,Icon:H},{id:`models`,tkey:`nav.models`,Icon:U},{id:`subagents`,tkey:`nav.subagents`,Icon:W},{id:`logs`,tkey:`nav.logs`,Icon:ee},{id:`usage`,tkey:`nav.usage`,Icon:re},{id:`storage`,tkey:`nav.storage`,Icon:G},{id:`api`,tkey:`nav.api`,Icon:Oe},{id:`claude`,tkey:`nav.claude`,Icon:ke},{id:`grok`,tkey:`nav.grok`,Icon:U}],qf={light:Te,dark:Ee,system:De},Jf={light:`theme.light`,dark:`theme.dark`,system:`theme.system`};function Yf(e){if(!e||typeof e!=`object`||!(`version`in e))return null;let t=e.version;return typeof t==`string`&&t.length>0?t:null}function Xf(){let e=localStorage.getItem(Gf);return e===`light`||e===`dark`?e:`system`}function Zf(){let{page:e,navigateToPage:t}=Rf(),[n,r]=(0,_.useState)(Xf),{locale:i,setLocale:a}=Ve(),o=K(),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(null),u=(0,_.useRef)(null),d=(0,_.useRef)(!1);(0,_.useEffect)(()=>{let e=()=>c(!1);return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[]),(0,_.useEffect)(()=>{let e=document.documentElement;n===`system`?(e.removeAttribute(`data-theme`),localStorage.removeItem(Gf)):(e.setAttribute(`data-theme`,n),localStorage.setItem(Gf,n))},[n]);let f=I(`app-healthz:${Wf}`,[],async e=>{let t=await fetch(`${Wf}/healthz`,{signal:e});return t.ok?Yf(await t.json()):null},{pollMs:3e4}),p=()=>r(e=>e===`light`?`dark`:e===`dark`?`system`:`light`),m=qf[n],h=f.data??`2.8.0-cs.6`,[g,v]=(0,_.useState)(!1),y=(0,_.useCallback)(async e=>{let t=await ut(await fetch(`${Wf}/api/claude-code`,{signal:e}));return t&&typeof t.enabled==`boolean`?t.enabled:null},[]),b=I(`app-claude-code:${Wf}`,[],y).data??null,x=(0,_.useRef)(!1),[S,C]=(0,_.useState)(!1);(0,_.useEffect)(()=>{if(!s)return;let e=e=>{e.key===`Escape`&&c(!1)};window.addEventListener(`keydown`,e);let t=document.body.style.overflow;return document.body.style.overflow=`hidden`,()=>{window.removeEventListener(`keydown`,e),document.body.style.overflow=t}},[s]),(0,_.useEffect)(()=>{if(s){d.current=!0;let e=setTimeout(()=>u.current?.focus(),200);return()=>clearTimeout(e)}d.current&&(d.current=!1,l.current?.focus())},[s]),(0,_.useEffect)(()=>{let e=window.matchMedia(`(min-width: 761px)`),t=()=>{e.matches&&c(!1)};return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]);let w=async()=>{if(b===null||x.current)return;x.current=!0,C(!0);let e=!b;L(`app-claude-code:${Wf}`,e);try{(await fetch(`${Wf}/api/claude-code`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:e})})).ok||L(`app-claude-code:${Wf}`,!e)}catch{L(`app-claude-code:${Wf}`,!e)}finally{x.current=!1,C(!1)}},T=async()=>{if(!confirm(o(`dash.stopConfirm`)))return;v(!0);let e=await Hf(Wf,{formatFailure:e=>o(`dash.stopFailed`,{status:String(e)})});e.accepted||(v(!1),alert(e.message))},E=(0,z.jsxs)(`div`,{className:`brand`,children:[(0,z.jsx)(`span`,{className:`brand-logo`,role:`img`,"aria-label":o(`app.logoAria`)}),(0,z.jsx)(`span`,{className:`name`,children:`opencodex`}),(0,z.jsxs)(`span`,{className:`ver`,children:[`v`,h]})]});return(0,z.jsxs)(`div`,{className:`app`,children:[(0,z.jsxs)(`header`,{className:`mobile-topbar`,inert:s,children:[(0,z.jsx)(`button`,{ref:l,type:`button`,className:`menu-toggle`,onClick:()=>c(e=>!e),"aria-expanded":s,"aria-controls":`app-sidebar`,"aria-label":o(s?`nav.closeMenu`:`nav.openMenu`),title:o(s?`nav.closeMenu`:`nav.openMenu`),children:(0,z.jsx)(te,{})}),E,(0,z.jsx)(`button`,{type:`button`,className:`theme-toggle stop-toggle`,onClick:T,disabled:g,"aria-label":o(`dash.stop`),title:o(`dash.stop`),children:(0,z.jsx)(ye,{})})]}),s&&(0,z.jsx)(`div`,{className:`drawer-scrim`,onClick:()=>c(!1),"aria-hidden":`true`}),(0,z.jsxs)(`aside`,{id:`app-sidebar`,className:`sidebar${s?` open`:``}`,ref:u,tabIndex:-1,children:[(0,z.jsxs)(`div`,{className:`drawer-head`,children:[E,(0,z.jsx)(`button`,{type:`button`,className:`menu-toggle drawer-close`,onClick:()=>c(!1),"aria-label":o(`nav.closeMenu`),title:o(`nav.closeMenu`),children:(0,z.jsx)(ae,{})})]}),(0,z.jsx)(`nav`,{children:Kf.map(({id:n,tkey:r,Icon:i})=>(0,z.jsxs)(`div`,{className:`nav-entry${n===`claude`?` nav-entry-claude${e===n?` active`:``}`:``}`,children:[(0,z.jsxs)(`button`,{type:`button`,className:`nav-item${e===n?` active`:``}`,"data-page":n,onClick:()=>{t(n),c(!1)},"aria-current":e===n?`page`:void 0,children:[(0,z.jsx)(i,{}),` `,o(r)]}),n===`claude`&&b!==null&&(0,z.jsx)(it,{on:b,onClick:()=>void w(),disabled:S,label:o(`claude.toggleAria`)})]},n))}),(0,z.jsxs)(`div`,{className:`sidebar-foot`,children:[(0,z.jsxs)(`div`,{className:`lang-toggle`,children:[(0,z.jsx)(Oe,{"aria-hidden":!0}),(0,z.jsx)(at,{value:i,options:Ie.map(e=>({value:e.code,label:e.name})),onChange:e=>a(e),label:o(`lang.label`),placement:`right`,portal:!1,style:{flex:1,minWidth:0,width:`100%`}})]}),(0,z.jsxs)(`button`,{type:`button`,className:`theme-toggle`,onClick:p,"aria-label":`${o(`theme.label`)}: ${o(Jf[n])}`,title:`${o(`theme.label`)}: ${o(Jf[n])}`,children:[(0,z.jsx)(m,{}),` `,(0,z.jsx)(`span`,{className:`mode`,children:o(Jf[n])})]}),(0,z.jsxs)(`button`,{type:`button`,className:`theme-toggle stop-toggle`,onClick:T,disabled:g,"aria-label":o(`dash.stop`),title:o(`dash.stop`),children:[(0,z.jsx)(ye,{}),` `,(0,z.jsx)(`span`,{className:`mode`,children:o(g?`dash.stopping`:`dash.stop`)})]}),(0,z.jsx)(sf,{apiBase:Wf,onOpenUpdate:()=>{c(!1),t(`dashboard`,`update`)}})]})]}),(0,z.jsx)(`main`,{className:`main`,inert:s,children:(0,z.jsx)(`div`,{className:`main-inner${e===`combos`?` main-inner--combos`:``}`,children:(0,z.jsxs)(tf,{pageName:o(Uf[e]),title:o(`errorBoundary.title`),message:o(`errorBoundary.message`),detailsLabel:o(`errorBoundary.details`),reloadLabel:o(`errorBoundary.reload`),children:[e===`dashboard`&&(0,z.jsx)(Fn,{apiBase:Wf}),e===`startup`&&(0,z.jsx)(ef,{apiBase:Wf}),e===`providers`&&(0,z.jsx)(Po,{apiBase:Wf}),e===`models`&&(0,z.jsx)(Bs,{apiBase:Wf}),e===`combos`&&(0,z.jsx)(ic,{apiBase:Wf},Wf),e===`subagents`&&(0,z.jsx)(mc,{apiBase:Wf},Wf),e===`logs`&&(0,z.jsx)(Nl,{apiBase:Wf}),e===`usage`&&(0,z.jsx)(eu,{apiBase:Wf}),e===`storage`&&(0,z.jsx)(_u,{apiBase:Wf}),e===`codex-auth`&&(0,z.jsx)(xu,{apiBase:Wf}),e===`api`&&(0,z.jsx)(Zu,{apiBase:Wf}),e===`claude`&&(0,z.jsx)(Fd,{apiBase:Wf}),e===`grok`&&(0,z.jsx)(Vd,{apiBase:Wf})]},e)})})]})}g.createRoot(document.getElementById(`root`)).render((0,z.jsx)(_.StrictMode,{children:(0,z.jsx)(He,{children:(0,z.jsx)(Zf,{})})}));
|
package/gui/dist/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
} catch (e) {}
|
|
17
17
|
})();
|
|
18
18
|
</script>
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-pD7leCGr.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-OY43ubAq.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coseung2/opencodex",
|
|
3
|
-
"version": "2.8.0-cs.
|
|
3
|
+
"version": "2.8.0-cs.6",
|
|
4
4
|
"description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./bin/package-main.mjs",
|
|
@@ -32,6 +32,7 @@ For OCX 2.8+, the notch automatically reads the existing `%USERPROFILE%\.opencod
|
|
|
32
32
|
- `/api/usage?range=7d` refreshes around every 30 seconds; only the newest calendar day's model rows are aggregated into the displayed per-provider usage.
|
|
33
33
|
- `/api/logs?tail=10` refreshes every ~2 seconds only while the Logs tab is visible. The response replaces the in-memory list, newest first, and OCX Notch never persists logs itself.
|
|
34
34
|
- OpenAI account state and per-account quotas refresh around every 5 seconds. Other provider configuration, account pools, and cached `/api/provider-quotas` refresh around every 5 minutes. For xAI OAuth, OCX reports the authoritative weekly Grok credit-pool usage and reset; the separate monthly spending cap is not presented as quota.
|
|
35
|
+
- Provider setup reads OCX's `/api/provider-presets` catalog on demand. OAuth status is polled only while a browser/device sign-in or account reauthentication is active; device authorization URLs, instructions, and user codes remain visible in the modal.
|
|
35
36
|
- `/api/system/memory` is requested only while expanded, at most every ~45 seconds, for optional heap detail.
|
|
36
37
|
|
|
37
38
|
All HTTP calls use WinHTTP against `127.0.0.1:10100`. There is no WebView, database, persistent usage history, runtime download, or automatic startup behavior. The last window position and width are stored in `%LOCALAPPDATA%\OCX Notch\window.json`.
|
|
@@ -50,8 +51,9 @@ Startup failures and Rust panics are written to the bounded diagnostic log `%LOC
|
|
|
50
51
|
- Drag anywhere on the notch to move it; its chosen position is preserved while it expands, collapses, or refreshes.
|
|
51
52
|
- Click a provider with multiple accounts to expand or collapse its account rows.
|
|
52
53
|
- Click the pause icon beside an OpenAI account to exclude it from the rotation pool. A paused account shows a play icon that includes it again. The icon updates immediately and rolls back if OCX rejects the request.
|
|
54
|
+
- Accounts that require renewed credentials expose an inline **재인증** action on the same row. OpenAI's main account is intentionally excluded; eligible OpenAI pool and generic OAuth accounts can start, cancel, and retry browser authentication.
|
|
53
55
|
- Providers with quota data are shown first. Providers with usage but no quota stay behind the inline usage-only toggle.
|
|
54
56
|
- Press **Esc** to collapse.
|
|
55
|
-
- Right-click to set the real OCX account rotation threshold, fine-tune it by 1%, **Refresh**, or **Exit**. `Off` writes threshold `0`.
|
|
57
|
+
- Right-click to add a provider, set the real OCX account rotation threshold, fine-tune it by 1%, **Refresh**, or **Exit**. The opaque provider modal groups supported presets into Account, Free, and Paid tabs. Canonical OpenAI adds another Codex account, OAuth presets use browser/device authorization, and required-key presets use masked API-key entry. Local, key-optional, endpoint-choice, and placeholder-URL presets are omitted because this compact modal cannot preserve those setup contracts safely. `Off` writes threshold `0`.
|
|
56
58
|
|
|
57
59
|
Quota percentages are shown as used percentages with the same 5-hour/weekly/monthly/custom-window rows, reset countdowns, 5px progress bars, green fill, and green-to-amber threshold warning used by the OCX dashboard. Provider usage is merged by exact provider name, limited to the newest day, and formatted with Korean `만/억/조` units. OpenAI account rows show their own weekly/monthly quotas; OAuth and key-pool rows show their masked identity and active/health state, while provider-level quota remains associated with the active account. The native window uses a subtle 238/255 global alpha.
|
package/src/cli/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { stripGrokConfig } from "../grok/inject";
|
|
|
5
5
|
import { restoreLegacyOpenaiHistory } from "../codex/history-provider";
|
|
6
6
|
import { reconcileJournal } from "../codex/journal";
|
|
7
7
|
import {
|
|
8
|
+
applyProxyEnv,
|
|
8
9
|
codexAutoStartEnabled,
|
|
9
10
|
getConfigDir,
|
|
10
11
|
loadConfig,
|
|
@@ -25,7 +26,7 @@ import { runTrayProxyRestart, runTrayProxyStart } from "./tray-proxy";
|
|
|
25
26
|
import { installCrashGuards } from "../lib/crash-guard";
|
|
26
27
|
import { hasHelpFlag, printSubcommandUsage, printUsage, printVersion } from "./help";
|
|
27
28
|
import { findAvailablePort, isAddrInUse, PortUnavailableError, shouldPersistSelectedPort, waitForPortAvailable } from "../server/ports";
|
|
28
|
-
import { findLiveProxy, probeHostname, type LiveProxy } from "../server/proxy-liveness";
|
|
29
|
+
import { findLiveProxy, probeHostname, proxyIdentityAt, type LiveProxy } from "../server/proxy-liveness";
|
|
29
30
|
import { stopProxy } from "../lib/process-control";
|
|
30
31
|
import { loadServiceTokenFromFile } from "../lib/service-secrets";
|
|
31
32
|
import { diagnoseService, isServiceOwnershipError, serviceCommand, serviceEnvironmentOwnedHere, serviceStartableFromTray, serviceStatusSummary, stopServiceIfInstalled, uninstallServiceIfInstalled } from "../service";
|
|
@@ -64,7 +65,7 @@ if (command !== undefined && command !== "help" && hasHelpFlag(args.slice(1))) {
|
|
|
64
65
|
process.exit(0);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
maybeAutoRestoreCodexShim(command, args);
|
|
68
|
+
if (command !== "start") maybeAutoRestoreCodexShim(command, args);
|
|
68
69
|
|
|
69
70
|
function parsePortOption(): number | undefined {
|
|
70
71
|
if (args.length === 1) return undefined;
|
|
@@ -119,16 +120,22 @@ function startArgv(port?: number): string[] {
|
|
|
119
120
|
return args;
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
function rejectAlreadyRunning(live: LiveProxy, fallbackPid: number | null = null): never {
|
|
124
|
+
console.error(`⚠️ Proxy already running (PID ${live.pid ?? fallbackPid ?? "unknown"}, port ${live.port}). Use 'ocx stop' first.`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
122
128
|
async function chooseListenPort(requestedPort?: number): Promise<number> {
|
|
123
129
|
const config = loadConfig();
|
|
124
130
|
const preferred = requestedPort ?? config.port ?? 10100;
|
|
125
131
|
const hardPin = requestedPort !== undefined && requestedPort > 0;
|
|
132
|
+
const hostname = config.hostname ?? "127.0.0.1";
|
|
126
133
|
// Soft start: brief prefer-retry then ephemeral hop.
|
|
127
134
|
// Explicit `--port` (service wrappers / update restart): wait for the pinned port
|
|
128
135
|
// to free without killing any listener (healthy ocx / foreign). Never hop.
|
|
129
136
|
if (hardPin && preferred > 0) {
|
|
130
137
|
const { reclaimListenPort } = await import("../server/port-reclaim");
|
|
131
|
-
await reclaimListenPort(preferred,
|
|
138
|
+
await reclaimListenPort(preferred, hostname, {
|
|
132
139
|
// Ghost LISTEN rows with a dead PID can outlive the process for a while.
|
|
133
140
|
// SetTcpEntry(DELETE_TCB) needs elevation (often returns 317), so the only
|
|
134
141
|
// reliable non-admin recovery is to wait for the OS to release the TCB.
|
|
@@ -139,49 +146,67 @@ async function chooseListenPort(requestedPort?: number): Promise<number> {
|
|
|
139
146
|
dropTcpRows: true,
|
|
140
147
|
});
|
|
141
148
|
}
|
|
149
|
+
let selected: number;
|
|
142
150
|
try {
|
|
143
|
-
|
|
151
|
+
selected = await findAvailablePort(preferred, hostname, {
|
|
144
152
|
// After reclaim, keep probing briefly — ghost rows sometimes clear between
|
|
145
153
|
// the reclaim deadline and the final listen. Still never hop off `--port`.
|
|
146
154
|
preferRetryMs: hardPin ? 5_000 : 750,
|
|
147
155
|
preferRetryIntervalMs: 50,
|
|
148
|
-
allowEphemeralFallback:
|
|
156
|
+
allowEphemeralFallback: false,
|
|
149
157
|
});
|
|
150
|
-
if (preferred > 0 && selected !== preferred) {
|
|
151
|
-
console.log(`⚠️ Port ${preferred} is busy; starting opencodex on ${selected}.`);
|
|
152
|
-
}
|
|
153
|
-
if (shouldPersistSelectedPort(config.port, selected, preferred)) {
|
|
154
|
-
config.port = selected;
|
|
155
|
-
saveConfig(config);
|
|
156
|
-
}
|
|
157
|
-
return selected;
|
|
158
158
|
} catch (err) {
|
|
159
|
-
if (err instanceof PortUnavailableError) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
if (err instanceof PortUnavailableError && !hardPin) {
|
|
160
|
+
// Runtime files are advisory: a live proxy can still own the preferred listener when
|
|
161
|
+
// both records are absent or stale. Check that listener before allocating an ephemeral
|
|
162
|
+
// port, so a missed discovery pass cannot shadow it and overwrite fresh runtime state.
|
|
163
|
+
if (preferred > 0) {
|
|
164
|
+
const identity = await proxyIdentityAt(preferred, { hostname });
|
|
165
|
+
if (identity) {
|
|
166
|
+
rejectAlreadyRunning({ pid: null, port: preferred, hostname, source: "config" });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const live = await findLiveProxy();
|
|
170
|
+
if (live) rejectAlreadyRunning(live);
|
|
171
|
+
selected = await findAvailablePort(0, hostname);
|
|
172
|
+
if (preferred > 0) {
|
|
173
|
+
console.log(`⚠️ Port ${preferred} is busy; starting opencodex on ${selected}.`);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
if (err instanceof PortUnavailableError) {
|
|
177
|
+
console.error(`❌ ${err.message}`);
|
|
178
|
+
console.error(" Stop whatever holds that port, or change config.port, then retry.");
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
throw err;
|
|
163
182
|
}
|
|
164
|
-
throw err;
|
|
165
183
|
}
|
|
184
|
+
if (shouldPersistSelectedPort(config.port, selected, preferred)) {
|
|
185
|
+
config.port = selected;
|
|
186
|
+
saveConfig(config);
|
|
187
|
+
}
|
|
188
|
+
return selected;
|
|
166
189
|
}
|
|
167
190
|
|
|
168
191
|
async function handleStart(options: { block?: boolean } = {}) {
|
|
192
|
+
const requestedPort = parsePortOption();
|
|
193
|
+
// Identity probes must stay direct even when the shell supplied HTTP_PROXY
|
|
194
|
+
// without NO_PROXY. startServer applies the same idempotent normalization.
|
|
195
|
+
applyProxyEnv(loadConfig());
|
|
196
|
+
const existingPid = readPid();
|
|
197
|
+
const live = await findLiveProxy();
|
|
198
|
+
if (live) rejectAlreadyRunning(live, existingPid);
|
|
199
|
+
maybeAutoRestoreCodexShim(command, args);
|
|
200
|
+
if (existingPid) {
|
|
201
|
+
removePid(existingPid);
|
|
202
|
+
}
|
|
203
|
+
|
|
169
204
|
// Native (WinSW) service mode has no batch wrapper to read the service token file
|
|
170
205
|
// into the environment, so the app loads it here before the server binds. The server
|
|
171
206
|
// auth path reads OPENCODEX_API_AUTH_TOKEN from the environment.
|
|
172
207
|
const serviceToken = loadServiceTokenFromFile(process.env);
|
|
173
208
|
if (serviceToken) process.env.OPENCODEX_API_AUTH_TOKEN = serviceToken;
|
|
174
|
-
const requestedPort = parsePortOption();
|
|
175
209
|
if (!currentExternalCodexModelProvider()) reconcileJournal();
|
|
176
|
-
const existingPid = readPid();
|
|
177
|
-
if (existingPid) {
|
|
178
|
-
const live = await findLiveProxy();
|
|
179
|
-
if (live) {
|
|
180
|
-
console.error(`⚠️ Proxy already running (PID ${live.pid ?? existingPid}, port ${live.port}). Use 'ocx stop' first.`);
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
removePid(existingPid);
|
|
184
|
-
}
|
|
185
210
|
|
|
186
211
|
// Interactive-only update prompt. Must run BEFORE we bind a port / write a
|
|
187
212
|
// PID: choosing "Update now" installs globally and exits, so we never want a
|
|
@@ -213,16 +238,29 @@ async function handleStart(options: { block?: boolean } = {}) {
|
|
|
213
238
|
}
|
|
214
239
|
continue;
|
|
215
240
|
}
|
|
241
|
+
const live = await findLiveProxy();
|
|
242
|
+
if (live) rejectAlreadyRunning(live);
|
|
216
243
|
console.log(`⚠️ Port ${port} was taken while starting; picking another...`);
|
|
217
244
|
port = await chooseListenPort(requestedPort);
|
|
218
245
|
}
|
|
219
246
|
}
|
|
247
|
+
const config = loadConfig();
|
|
248
|
+
const preferred = requestedPort ?? config.port ?? 10100;
|
|
249
|
+
if (port !== preferred && preferred > 0) {
|
|
250
|
+
// Recheck immediately before any runtime-state write: another proxy may have won the
|
|
251
|
+
// preferred listener after soft fallback selection completed.
|
|
252
|
+
const identity = await proxyIdentityAt(preferred, { hostname: config.hostname });
|
|
253
|
+
if (identity) {
|
|
254
|
+
server.stop(true);
|
|
255
|
+
rejectAlreadyRunning({ pid: null, port: preferred, hostname: config.hostname, source: "config" });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
220
259
|
// A single request's streaming error must never crash the daemon serving every
|
|
221
260
|
// other Codex session — capture the full stack to crash.log and stay up.
|
|
222
261
|
installCrashGuards();
|
|
223
262
|
writePid(process.pid);
|
|
224
263
|
|
|
225
|
-
const config = loadConfig();
|
|
226
264
|
writeRuntimePort({ pid: process.pid, port, hostname: config.hostname });
|
|
227
265
|
// No pre-emptive snapshot here. `injectCodexConfig` journals the exact bytes it
|
|
228
266
|
// is about to transform; snapshotting earlier only captured a baseline that could
|
package/src/config.ts
CHANGED
|
@@ -2045,9 +2045,10 @@ export function resolveEnvValue(value: string | undefined): string | undefined {
|
|
|
2045
2045
|
*/
|
|
2046
2046
|
export function applyProxyEnv(config: OcxConfig): void {
|
|
2047
2047
|
const proxy = resolveEnvValue(config.proxy);
|
|
2048
|
-
if (
|
|
2049
|
-
|
|
2050
|
-
|
|
2048
|
+
if (proxy) {
|
|
2049
|
+
if (!process.env.HTTP_PROXY?.trim() && !process.env.http_proxy?.trim()) process.env.HTTP_PROXY = proxy;
|
|
2050
|
+
if (!process.env.HTTPS_PROXY?.trim() && !process.env.https_proxy?.trim()) process.env.HTTPS_PROXY = proxy;
|
|
2051
|
+
}
|
|
2051
2052
|
const existing = process.env.NO_PROXY ?? process.env.no_proxy ?? "";
|
|
2052
2053
|
const entries = existing.split(",").map(s => s.trim()).filter(Boolean);
|
|
2053
2054
|
const seen = new Set(entries.map(e => e.toLowerCase()));
|
|
@@ -728,6 +728,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
|
|
|
728
728
|
baseUrl: "https://runtime.us-east-1.kiro.dev",
|
|
729
729
|
authKind: "oauth",
|
|
730
730
|
oauthId: "kiro",
|
|
731
|
+
dashboardPreset: true,
|
|
731
732
|
note: "Import-first: reuses your installed and signed-in Kiro CLI session (requires `kiro-cli login`). Add account logs `kiro-cli` out, switches it through a fresh browser login, stores the account by profile ARN, and restores the previous CLI session on cancellation or failure. Experimental third-party harness — see Kiro ToS.",
|
|
732
733
|
models: KIRO_MODELS,
|
|
733
734
|
defaultModel: "kiro-auto",
|
package/src/server/lifecycle.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface ActiveTurnLease extends AdmissionLease {
|
|
|
34
34
|
const activeTurns = new Map<AbortController, ActiveTurnLease>();
|
|
35
35
|
const admittedTurns = new Set<ActiveTurnLease>();
|
|
36
36
|
const knownTurnControllers = new WeakSet<AbortController>();
|
|
37
|
+
export type ActiveTurnsIdleListener = () => void;
|
|
38
|
+
const activeTurnsIdleListeners = new Set<ActiveTurnsIdleListener>();
|
|
37
39
|
let turnReleaseMisses = 0;
|
|
38
40
|
let draining = false;
|
|
39
41
|
let recyclingForExit = false;
|
|
@@ -41,6 +43,26 @@ let _serverRef: ReturnType<typeof Bun.serve> | undefined;
|
|
|
41
43
|
|
|
42
44
|
export function setServerRef(server: ReturnType<typeof Bun.serve> | undefined): void { _serverRef = server; }
|
|
43
45
|
export function setDraining(value: boolean): void { draining = value; }
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to the synchronous transition where the final admitted turn is
|
|
48
|
+
* released. The callback runs after the lease and admission gate are settled,
|
|
49
|
+
* so an observer can perform an idle-only action without racing a request on
|
|
50
|
+
* the event loop. Returns an unsubscribe function for bounded observers.
|
|
51
|
+
*/
|
|
52
|
+
export function onActiveTurnsIdle(listener: ActiveTurnsIdleListener): () => void {
|
|
53
|
+
activeTurnsIdleListeners.add(listener);
|
|
54
|
+
return () => { activeTurnsIdleListeners.delete(listener); };
|
|
55
|
+
}
|
|
56
|
+
function notifyActiveTurnsIdle(): void {
|
|
57
|
+
if (admittedTurns.size !== 0) return;
|
|
58
|
+
for (const listener of [...activeTurnsIdleListeners]) {
|
|
59
|
+
try {
|
|
60
|
+
listener();
|
|
61
|
+
} catch {
|
|
62
|
+
// An idle observer must never break turn release or request teardown.
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
44
66
|
export function tryAdmitTurn(): ActiveTurnLease | null {
|
|
45
67
|
const gateLease = turnGate.tryAcquire();
|
|
46
68
|
if (!gateLease) return null;
|
|
@@ -68,6 +90,7 @@ export function tryAdmitTurn(): ActiveTurnLease | null {
|
|
|
68
90
|
}
|
|
69
91
|
controllers.clear();
|
|
70
92
|
gateLease.release();
|
|
93
|
+
notifyActiveTurnsIdle();
|
|
71
94
|
},
|
|
72
95
|
};
|
|
73
96
|
admittedTurns.add(lease);
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Memory watchdog (#314 WP3 / #509) —
|
|
3
|
-
* native-memory
|
|
2
|
+
* Memory watchdog (#314 WP3 / #509) — observability plus a bounded Windows
|
|
3
|
+
* native-memory reclamation attempt for the Bun fetch-buffer retention shape.
|
|
4
4
|
*
|
|
5
5
|
* Samples process.memoryUsage() on an unref'd interval into a bounded ring and
|
|
6
|
-
* logs ONE rate-limited warning when observed memory crosses the threshold.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* instance is a module-level singleton so
|
|
10
|
-
* snapshot without threading server state
|
|
6
|
+
* logs ONE rate-limited warning when observed memory crosses the threshold. On
|
|
7
|
+
* Windows, a supported Bun.gc(true) is attempted once per pressure episode,
|
|
8
|
+
* only after observed memory reaches the reclamation threshold and the active
|
|
9
|
+
* turn registry is idle. The active instance is a module-level singleton so
|
|
10
|
+
* the management API can expose the snapshot without threading server state
|
|
11
|
+
* through route contexts.
|
|
11
12
|
*
|
|
12
13
|
* Privacy: samples are scalar numbers only; the warn line never interpolates
|
|
13
14
|
* paths, hostnames, or tokens.
|
|
14
15
|
*/
|
|
15
16
|
|
|
17
|
+
import { getActiveTurnCount, onActiveTurnsIdle } from "./lifecycle";
|
|
18
|
+
|
|
16
19
|
export type MemorySampleBase = {
|
|
17
20
|
/** Epoch ms. */
|
|
18
21
|
at: number;
|
|
@@ -52,6 +55,7 @@ export type MemoryWatchdog = {
|
|
|
52
55
|
|
|
53
56
|
const DEFAULT_INTERVAL_MS = 60_000;
|
|
54
57
|
const DEFAULT_WARN_THRESHOLD_BYTES = 4 * 1024 ** 3; // 4 GiB
|
|
58
|
+
const DEFAULT_RECLAIM_THRESHOLD_BYTES = 2 * 1024 ** 3; // 2 GiB, based on Windows reproduction
|
|
55
59
|
const DEFAULT_RING_SIZE = 360; // ≈6h at 60s
|
|
56
60
|
const WARN_INTERVAL_MS = 30 * 60_000;
|
|
57
61
|
const DOCS_URL = "https://opencodex.me/troubleshooting/windows-memory/";
|
|
@@ -71,6 +75,24 @@ export function observedMemoryCounter(sample: Pick<MemorySampleBase, "rss" | "ex
|
|
|
71
75
|
return { observedBytes: best.bytes, observedMetric: best.metric };
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
export type MemoryReclamationPolicyInput = {
|
|
79
|
+
observedBytes: number;
|
|
80
|
+
pressureThresholdBytes: number;
|
|
81
|
+
activeTurns: number;
|
|
82
|
+
platform: NodeJS.Platform;
|
|
83
|
+
gcSupported: boolean;
|
|
84
|
+
pressureLatched: boolean;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/** Pure policy gate for the pressure-triggered, idle-only reclamation path. */
|
|
88
|
+
export function shouldAttemptMemoryReclamation(input: MemoryReclamationPolicyInput): boolean {
|
|
89
|
+
return input.platform === "win32"
|
|
90
|
+
&& input.gcSupported
|
|
91
|
+
&& input.activeTurns === 0
|
|
92
|
+
&& input.observedBytes >= input.pressureThresholdBytes
|
|
93
|
+
&& !input.pressureLatched;
|
|
94
|
+
}
|
|
95
|
+
|
|
74
96
|
/** The running watchdog, if any — read by /api/system/memory. */
|
|
75
97
|
export function getActiveMemoryWatchdog(): MemoryWatchdog | null {
|
|
76
98
|
return active;
|
|
@@ -93,6 +115,12 @@ function normalizeSample(sample: MemorySampleBase): MemorySample {
|
|
|
93
115
|
return { ...sample, ...observedMemoryCounter(sample) };
|
|
94
116
|
}
|
|
95
117
|
|
|
118
|
+
function defaultGarbageCollector(platform: NodeJS.Platform): (() => void) | null {
|
|
119
|
+
if (platform !== "win32") return null;
|
|
120
|
+
if (typeof Bun === "undefined" || typeof Bun.gc !== "function") return null;
|
|
121
|
+
return () => Bun.gc(true);
|
|
122
|
+
}
|
|
123
|
+
|
|
96
124
|
/**
|
|
97
125
|
* Start (or replace) the process-wide memory watchdog. Idempotent: a previous
|
|
98
126
|
* active instance is stopped first, so repeated startServer() calls in tests
|
|
@@ -102,23 +130,57 @@ function normalizeSample(sample: MemorySampleBase): MemorySample {
|
|
|
102
130
|
export function startMemoryWatchdog(opts?: {
|
|
103
131
|
intervalMs?: number;
|
|
104
132
|
warnThresholdBytes?: number;
|
|
133
|
+
pressureThresholdBytes?: number;
|
|
105
134
|
ringSize?: number;
|
|
106
135
|
now?: () => number;
|
|
107
136
|
sample?: () => MemorySampleBase;
|
|
108
137
|
warn?: (msg: string) => void;
|
|
138
|
+
platform?: NodeJS.Platform;
|
|
139
|
+
activeTurnCount?: () => number;
|
|
140
|
+
gc?: (() => void) | null;
|
|
109
141
|
}): MemoryWatchdog {
|
|
110
142
|
active?.stop();
|
|
111
143
|
const intervalMs = opts?.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
112
144
|
const warnThresholdBytes = opts?.warnThresholdBytes ?? DEFAULT_WARN_THRESHOLD_BYTES;
|
|
145
|
+
const pressureThresholdBytes = opts?.pressureThresholdBytes ?? DEFAULT_RECLAIM_THRESHOLD_BYTES;
|
|
113
146
|
const ringSize = opts?.ringSize ?? DEFAULT_RING_SIZE;
|
|
114
147
|
const now = opts?.now ?? Date.now;
|
|
115
148
|
const sample = opts?.sample ?? (() => defaultSample(now));
|
|
116
149
|
const warn = opts?.warn ?? ((msg: string) => console.warn(msg));
|
|
150
|
+
const platform = opts?.platform ?? process.platform;
|
|
151
|
+
const activeTurnCount = opts?.activeTurnCount ?? getActiveTurnCount;
|
|
152
|
+
const collectGarbage = opts !== undefined && "gc" in opts
|
|
153
|
+
? opts.gc ?? null
|
|
154
|
+
: defaultGarbageCollector(platform);
|
|
117
155
|
|
|
118
156
|
const samples: MemorySample[] = [];
|
|
119
157
|
let lastWarnAt: number | null = null;
|
|
120
158
|
let observedBytes = 0;
|
|
121
159
|
let observedMetric: MemoryMetric = "rss";
|
|
160
|
+
let pressureLatched = false;
|
|
161
|
+
|
|
162
|
+
const reclaimIfIdle = (): void => {
|
|
163
|
+
if (!shouldAttemptMemoryReclamation({
|
|
164
|
+
observedBytes,
|
|
165
|
+
pressureThresholdBytes,
|
|
166
|
+
activeTurns: activeTurnCount(),
|
|
167
|
+
platform,
|
|
168
|
+
gcSupported: collectGarbage !== null,
|
|
169
|
+
pressureLatched,
|
|
170
|
+
})) return;
|
|
171
|
+
// Latch before calling Bun.gc so a sustained high sample cannot turn into
|
|
172
|
+
// a GC on every timer tick or every later turn completion.
|
|
173
|
+
pressureLatched = true;
|
|
174
|
+
try {
|
|
175
|
+
collectGarbage?.();
|
|
176
|
+
} catch {
|
|
177
|
+
// Reclamation is a best-effort runtime hint. A collector failure must not
|
|
178
|
+
// escape the watchdog timer and terminate the proxy.
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const removeIdleListener = platform === "win32" && collectGarbage !== null
|
|
182
|
+
? onActiveTurnsIdle(reclaimIfIdle)
|
|
183
|
+
: () => {};
|
|
122
184
|
|
|
123
185
|
const tick = () => {
|
|
124
186
|
let s: MemorySample;
|
|
@@ -131,6 +193,8 @@ export function startMemoryWatchdog(opts?: {
|
|
|
131
193
|
if (samples.length > ringSize) samples.splice(0, samples.length - ringSize);
|
|
132
194
|
observedBytes = s.observedBytes;
|
|
133
195
|
observedMetric = s.observedMetric;
|
|
196
|
+
if (observedBytes < pressureThresholdBytes) pressureLatched = false;
|
|
197
|
+
reclaimIfIdle();
|
|
134
198
|
if (s.observedBytes >= warnThresholdBytes && (lastWarnAt === null || now() - lastWarnAt >= WARN_INTERVAL_MS)) {
|
|
135
199
|
lastWarnAt = now();
|
|
136
200
|
const observedMb = Math.round(s.observedBytes / (1024 * 1024));
|
|
@@ -145,6 +209,7 @@ export function startMemoryWatchdog(opts?: {
|
|
|
145
209
|
const instance: MemoryWatchdog = {
|
|
146
210
|
stop() {
|
|
147
211
|
clearInterval(timer);
|
|
212
|
+
removeIdleListener();
|
|
148
213
|
if (active === instance) active = null;
|
|
149
214
|
},
|
|
150
215
|
snapshot() {
|
|
@@ -68,7 +68,11 @@ export interface LiveProxy {
|
|
|
68
68
|
*/
|
|
69
69
|
export function probeHostname(hostname: string | undefined): string {
|
|
70
70
|
const trimmed = (hostname ?? "").trim();
|
|
71
|
-
if (!trimmed || trimmed === "0.0.0.0" || trimmed === "::" || trimmed === "[::]")
|
|
71
|
+
if (!trimmed || /^localhost$/i.test(trimmed) || trimmed === "0.0.0.0" || trimmed === "::" || trimmed === "[::]") {
|
|
72
|
+
// startServer canonicalizes localhost to IPv4 loopback because Codex's injected URL does
|
|
73
|
+
// the same. Keep liveness probes on that exact address (Windows otherwise prefers ::1).
|
|
74
|
+
return "127.0.0.1";
|
|
75
|
+
}
|
|
72
76
|
if (trimmed.startsWith("[") && trimmed.endsWith("]")) return trimmed;
|
|
73
77
|
return trimmed.includes(":") ? `[${trimmed}]` : trimmed;
|
|
74
78
|
}
|
|
Binary file
|