omniroute 2.8.4 → 2.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/app/.next/BUILD_ID +1 -1
  2. package/app/.next/build-manifest.json +2 -2
  3. package/app/.next/prerender-manifest.json +3 -3
  4. package/app/.next/server/app/(dashboard)/dashboard/a2a/page_client-reference-manifest.js +1 -1
  5. package/app/.next/server/app/(dashboard)/dashboard/agents/page_client-reference-manifest.js +1 -1
  6. package/app/.next/server/app/(dashboard)/dashboard/analytics/page_client-reference-manifest.js +1 -1
  7. package/app/.next/server/app/(dashboard)/dashboard/api-manager/page_client-reference-manifest.js +1 -1
  8. package/app/.next/server/app/(dashboard)/dashboard/audit-log/page_client-reference-manifest.js +1 -1
  9. package/app/.next/server/app/(dashboard)/dashboard/auto-combo/page_client-reference-manifest.js +1 -1
  10. package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  11. package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/app/.next/server/app/(dashboard)/dashboard/costs/page_client-reference-manifest.js +1 -1
  13. package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/(dashboard)/dashboard/health/page_client-reference-manifest.js +1 -1
  15. package/app/.next/server/app/(dashboard)/dashboard/limits/page_client-reference-manifest.js +1 -1
  16. package/app/.next/server/app/(dashboard)/dashboard/logs/page_client-reference-manifest.js +1 -1
  17. package/app/.next/server/app/(dashboard)/dashboard/mcp/page_client-reference-manifest.js +1 -1
  18. package/app/.next/server/app/(dashboard)/dashboard/media/page_client-reference-manifest.js +1 -1
  19. package/app/.next/server/app/(dashboard)/dashboard/onboarding/page_client-reference-manifest.js +1 -1
  20. package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/app/.next/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  22. package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  23. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  24. package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  25. package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  26. package/app/.next/server/app/(dashboard)/dashboard/search-tools/page_client-reference-manifest.js +1 -1
  27. package/app/.next/server/app/(dashboard)/dashboard/settings/page_client-reference-manifest.js +1 -1
  28. package/app/.next/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  29. package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  30. package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  31. package/app/.next/server/app/400/page_client-reference-manifest.js +1 -1
  32. package/app/.next/server/app/401/page_client-reference-manifest.js +1 -1
  33. package/app/.next/server/app/403/page_client-reference-manifest.js +1 -1
  34. package/app/.next/server/app/408/page_client-reference-manifest.js +1 -1
  35. package/app/.next/server/app/429/page_client-reference-manifest.js +1 -1
  36. package/app/.next/server/app/500/page_client-reference-manifest.js +1 -1
  37. package/app/.next/server/app/502/page_client-reference-manifest.js +1 -1
  38. package/app/.next/server/app/503/page_client-reference-manifest.js +1 -1
  39. package/app/.next/server/app/_global-error.html +2 -2
  40. package/app/.next/server/app/_global-error.rsc +1 -1
  41. package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  42. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  43. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  44. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  45. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  46. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  47. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  48. package/app/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  49. package/app/.next/server/app/forbidden/page_client-reference-manifest.js +1 -1
  50. package/app/.next/server/app/forgot-password/page_client-reference-manifest.js +1 -1
  51. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  52. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  53. package/app/.next/server/app/maintenance/page_client-reference-manifest.js +1 -1
  54. package/app/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  55. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  56. package/app/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  57. package/app/.next/server/app/status/page_client-reference-manifest.js +1 -1
  58. package/app/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  59. package/app/.next/server/chunks/[root-of-the-server]__09c944b3._.js +1 -1
  60. package/app/.next/server/chunks/[root-of-the-server]__134baf4c._.js +1 -1
  61. package/app/.next/server/chunks/[root-of-the-server]__179c5303._.js +1 -1
  62. package/app/.next/server/chunks/[root-of-the-server]__237e5042._.js +1 -1
  63. package/app/.next/server/chunks/[root-of-the-server]__46fad57a._.js +1 -1
  64. package/app/.next/server/chunks/[root-of-the-server]__7d9b23e7._.js +1 -1
  65. package/app/.next/server/chunks/[root-of-the-server]__80e3bfc3._.js +2 -2
  66. package/app/.next/server/chunks/[root-of-the-server]__84e445b2._.js +1 -1
  67. package/app/.next/server/chunks/[root-of-the-server]__92cb0def._.js +1 -1
  68. package/app/.next/server/chunks/[root-of-the-server]__9bbd49c8._.js +1 -1
  69. package/app/.next/server/chunks/[root-of-the-server]__add0a68c._.js +1 -1
  70. package/app/.next/server/chunks/[root-of-the-server]__c393c81f._.js +1 -1
  71. package/app/.next/server/chunks/[root-of-the-server]__cd42b732._.js +1 -1
  72. package/app/.next/server/chunks/[root-of-the-server]__d4563e10._.js +1 -1
  73. package/app/.next/server/chunks/[root-of-the-server]__db2f9fe0._.js +1 -1
  74. package/app/.next/server/chunks/[root-of-the-server]__e27a89bd._.js +1 -1
  75. package/app/.next/server/chunks/[root-of-the-server]__e56edf04._.js +1 -1
  76. package/app/.next/server/chunks/[root-of-the-server]__e6e94646._.js +1 -1
  77. package/app/.next/server/chunks/[root-of-the-server]__eb98039a._.js +1 -1
  78. package/app/.next/server/chunks/[root-of-the-server]__f31b4656._.js +1 -1
  79. package/app/.next/server/chunks/_05c48915._.js +1 -1
  80. package/app/.next/server/chunks/_2115d8de._.js +1 -1
  81. package/app/.next/server/chunks/_3ac953eb._.js +1 -1
  82. package/app/.next/server/chunks/_4b8fd853._.js +1 -1
  83. package/app/.next/server/chunks/_68683848._.js +1 -1
  84. package/app/.next/server/chunks/_ee9b677b._.js +1 -1
  85. package/app/.next/server/chunks/open-sse_cf4d5692._.js +1 -1
  86. package/app/.next/server/chunks/open-sse_config_constants_ts_9583de19._.js +1 -1
  87. package/app/.next/server/chunks/open-sse_services_826884e1._.js +2 -1
  88. package/app/.next/server/chunks/ssr/[root-of-the-server]__9affb65e._.js +1 -1
  89. package/app/.next/server/chunks/ssr/[root-of-the-server]__a6942102._.js +1 -1
  90. package/app/.next/server/chunks/ssr/src_9197fb9b._.js +1 -1
  91. package/app/.next/server/chunks/ssr/src_lib_initCloudSync_ts_982b9d4d._.js +1 -1
  92. package/app/.next/server/pages/500.html +2 -2
  93. package/app/.next/server/server-reference-manifest.js +1 -1
  94. package/app/.next/server/server-reference-manifest.json +1 -1
  95. package/app/.next/static/chunks/{1e206030e7793015.js → d9a70775eb233dc3.js} +1 -1
  96. package/app/.next/static/chunks/{0f71d7fbf89bb737.js → ec1938d17386c6db.js} +1 -1
  97. package/app/CHANGELOG.md +24 -0
  98. package/app/docs/openapi.yaml +1 -1
  99. package/app/open-sse/config/constants.ts +3 -3
  100. package/app/open-sse/services/comboAgentMiddleware.ts +9 -1
  101. package/app/package-lock.json +2 -2
  102. package/app/package.json +1 -1
  103. package/app/src/shared/constants/cliTools.ts +2 -2
  104. package/app/tests/e2e/providers-bailian-coding-plan.spec.ts +14 -0
  105. package/package.json +1 -1
  106. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → coLESPH6_RrEzzULWq8F5}/_buildManifest.js +0 -0
  107. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → coLESPH6_RrEzzULWq8F5}/_clientMiddlewareManifest.json +0 -0
  108. /package/app/.next/static/{Ys6bRJXPNt8j-MKOjvZwp → coLESPH6_RrEzzULWq8F5}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@
4
4
  "model": "{{model}}",
5
5
  "provider": "openai",
6
6
  "apiKey": "{{apiKey}}"
7
- }`}},antigravity:{id:"antigravity",name:"Antigravity",image:"/providers/antigravity.png",color:"#4285F4",description:"Google Antigravity IDE with MITM",configType:"mitm",modelAliases:["claude-opus-4-6-thinking","claude-sonnet-4-6","gemini-3-flash","gpt-oss-120b-medium","gemini-3.1-pro-high","gemini-3.1-pro-low"],defaultModels:[{id:"gemini-3.1-pro-high",name:"Gemini 3.1 Pro High",alias:"gemini-3.1-pro-high"},{id:"gemini-3.1-pro-low",name:"Gemini 3.1 Pro Low",alias:"gemini-3.1-pro-low"},{id:"gemini-3-flash",name:"Gemini 3 Flash",alias:"gemini-3-flash"},{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6",alias:"claude-sonnet-4-6"},{id:"claude-opus-4-6-thinking",name:"Claude Opus 4.6 Thinking",alias:"claude-opus-4-6-thinking"},{id:"gpt-oss-120b-medium",name:"GPT OSS 120B Medium",alias:"gpt-oss-120b-medium"}]},copilot:{id:"copilot",name:"GitHub Copilot",image:"/providers/copilot.png",color:"#1F6FEB",description:"GitHub Copilot Chat — VS Code Extension",configType:"custom"},opencode:{id:"opencode",name:"OpenCode",image:"/providers/opencode.png",icon:"terminal",color:"#FF6B35",description:"OpenCode AI coding agent (Terminal)",configType:"guide",guideSteps:[{step:1,title:"Install OpenCode",desc:"Install via npm: npm install -g opencode-ai"},{step:2,title:"API Key",type:"apiKeySelector"},{step:3,title:"Set Base URL",desc:"opencode config set baseUrl {{baseUrl}}"},{step:4,title:"Select Model",type:"modelSelector"}]},kiro:{id:"kiro",name:"Kiro AI",image:"/providers/kiro.png",icon:"psychology_alt",color:"#FF6B35",description:"Amazon Kiro — AI-powered IDE",configType:"guide",guideSteps:[{step:1,title:"Open Kiro Settings",desc:"Go to Settings → AI Provider"},{step:2,title:"Base URL",value:"{{baseUrl}}",copyable:!0},{step:3,title:"API Key",type:"apiKeySelector"},{step:4,title:"Select Model",type:"modelSelector"}]}};e.i(313705);var n=e.i(25230),o=e.i(474078),c=e.i(95368),d=e.i(193464),d=d,x=e.i(657688),m=e.i(861745),u=e.i(948148);function p({effectiveConfigStatus:e,batchStatus:t,lastConfiguredAt:a=null}){let l=(0,u.useTranslations)("cliTools"),r=(0,m.useLocale)(),i=e||t?.configStatus||null,n={configured:{dotClass:"bg-green-500",badgeClass:"bg-green-500/10 text-green-600 dark:text-green-400",text:l("configured")},not_configured:{dotClass:"bg-yellow-500",badgeClass:"bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",text:l("notConfigured")},not_installed:{dotClass:"bg-zinc-400 dark:bg-zinc-500",badgeClass:"bg-zinc-500/10 text-zinc-500 dark:text-zinc-400",text:l("notInstalled")},other:{dotClass:"bg-blue-500",badgeClass:"bg-blue-500/10 text-blue-600 dark:text-blue-400",text:l("custom")},unknown:{dotClass:"bg-zinc-400 dark:bg-zinc-500",badgeClass:"bg-zinc-500/10 text-zinc-500 dark:text-zinc-400",text:l("unknown")}},o=i?n[i]||n.unknown:null;return(0,s.jsxs)(s.Fragment,{children:[o&&(0,s.jsxs)("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 text-[11px] font-medium rounded-full ${o.badgeClass}`,children:[(0,s.jsx)("span",{className:`size-1.5 rounded-full ${o.dotClass}`}),o.text]}),a?(0,s.jsxs)("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] text-text-muted",title:l("lastSavedAt",{date:new Date(a).toLocaleString(r)}),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"schedule"}),function(e,t){let s=Date.now()-new Date(e).getTime();if(s<0)return t("justNow");let a=Math.floor(s/1e3);if(a<60)return t("justNow");let l=Math.floor(a/60);if(l<60)return t("minutesAgoShort",{count:l});let r=Math.floor(l/60);if(r<24)return t("hoursAgoShort",{count:r});let i=Math.floor(r/24);if(i<30)return t("daysAgoShort",{count:i});let n=Math.floor(i/30);return n<12?t("monthsAgoShort",{count:n}):t("yearsAgoShort",{count:Math.floor(n/12)})}(a,l)]}):i&&"not_installed"!==i?(0,s.jsxs)("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"schedule"}),l("never")]}):null]})}let h=t.default.env.NEXT_PUBLIC_CLOUD_URL;function g({tool:e,isExpanded:t,onToggle:r,activeProviders:i,modelMappings:n,onModelMappingChange:m,baseUrl:g,hasActiveProviders:f,apiKeys:y,cloudEnabled:b,batchStatus:j,lastConfiguredAt:N}){let v,k,w,C=(0,u.useTranslations)("cliTools"),[S,_]=(0,a.useState)(null),[A,O]=(0,a.useState)(!1),[T,E]=(0,a.useState)(!1),[P,M]=(0,a.useState)(!1),[R,z]=(0,a.useState)(null),[I,B]=(0,a.useState)(!1),[K,U]=(0,a.useState)(!1),[D,$]=(0,a.useState)(null),[L,F]=(0,a.useState)(""),[H,J]=(0,a.useState)({}),[W,G]=(0,a.useState)(!1),[V,Y]=(0,a.useState)(""),q=(0,a.useRef)(!1),[X,Q]=(0,a.useState)([]),[Z,ee]=(0,a.useState)(!1),[et,es]=(0,a.useState)(null),ea=!!(S?.installed&&S?.runnable),el=(()=>{if(!ea)return null;let e=S.settings?.env?.ANTHROPIC_BASE_URL;if(!e)return"not_configured";let t=e.includes("localhost")||e.includes("127.0.0.1"),s=b&&h&&e.startsWith(h);return t||s?"configured":"other"})()||j?.configStatus||null;(0,a.useEffect)(()=>{y?.length>0&&!L&&F(y[0].key)},[y,L]),(0,a.useEffect)(()=>{t&&!S&&(ei(),er(),ed())},[t,S]);let er=async()=>{try{let e=await fetch("/api/models/alias"),t=await e.json();e.ok&&J(t.aliases||{})}catch(e){console.log("Error fetching model aliases:",e)}};(0,a.useEffect)(()=>{if(S?.installed&&!q.current){q.current=!0;let t=S.settings?.env||{};e.defaultModels.forEach(e=>{if(e.envKey){let s=t[e.envKey]||e.defaultValue||"";s&&m(e.alias,s)}});let s=t.ANTHROPIC_AUTH_TOKEN;s&&y?.some(e=>e.key===s)&&F(s)}},[S,y,e.defaultModels,m]);let ei=async()=>{O(!0);try{let e=await fetch("/api/cli-tools/claude-settings"),t=await e.json();_(t)}catch(e){_({installed:!1,error:e.message})}finally{O(!1)}},en=()=>{let e=V||g;return e.endsWith("/v1")?e:`${e}/v1`},eo=async()=>{E(!0),z(null);try{let t={ANTHROPIC_BASE_URL:en()},s=L?.trim()||(y?.length>0?y[0].key:null)||(b?null:"sk_omniroute");s&&(t.ANTHROPIC_AUTH_TOKEN=s),e.defaultModels.forEach(e=>{let s=n[e.alias];s&&e.envKey&&(t[e.envKey]=s)});let a=await fetch("/api/cli-tools/claude-settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({env:t})}),l=await a.json();a.ok?(z({type:"success",text:C("settingsApplied")}),_(e=>({...e,hasBackup:!0,settings:{...e?.settings,env:t}}))):z({type:"error",text:l.error||C("failedApplySettings")})}catch(e){z({type:"error",text:e.message})}finally{E(!1)}},ec=async()=>{M(!0),z(null);try{let t=await fetch("/api/cli-tools/claude-settings",{method:"DELETE"}),s=await t.json();t.ok?(z({type:"success",text:C("settingsReset")}),e.defaultModels.forEach(e=>m(e.alias,e.defaultValue||"")),F("")):z({type:"error",text:s.error||C("failedResetSettings")})}catch(e){z({type:"error",text:e.message})}finally{M(!1)}},ed=async()=>{try{let e=await fetch("/api/cli-tools/backups?tool=claude"),t=await e.json();e.ok&&Q(t.backups||[])}catch(e){console.log("Error fetching backups:",e)}},ex=async e=>{es(e),z(null);try{let t=await fetch("/api/cli-tools/backups",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool:"claude",backupId:e})}),s=await t.json();t.ok?(z({type:"success",text:C("backupRestored")}),ei(),ed()):z({type:"error",text:s.error||C("failedRestore")})}catch(e){z({type:"error",text:e.message})}finally{es(null)}};return(0,s.jsxs)(l.Card,{padding:"sm",className:"overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between hover:cursor-pointer",onClick:r,children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:(0,s.jsx)(x.default,{src:"/providers/claude.png",alt:e.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.currentTarget.style.display="none"}})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-medium text-sm",children:e.name}),(0,s.jsx)(p,{effectiveConfigStatus:el,batchStatus:j,lastConfiguredAt:N})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted truncate",children:C("toolDescriptions.claude")})]})]}),(0,s.jsx)("span",{className:`material-symbols-outlined text-text-muted text-[20px] transition-transform ${t?"rotate-180":""}`,children:"expand_more"})]}),t&&(0,s.jsxs)("div",{className:"mt-4 pt-4 border-t border-border flex flex-col gap-4",children:[A&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin",children:"progress_activity"}),(0,s.jsx)("span",{children:C("checkingCli",{tool:"Claude"})})]}),!A&&S&&!ea&&(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-yellow-500",children:"warning"}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("p",{className:"font-medium text-yellow-600 dark:text-yellow-400",children:S.installed?C("cliNotRunnable",{tool:"Claude"}):C("cliNotInstalled",{tool:"Claude"})}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:S.installed?C("cliFoundFailedHealthcheck",{tool:"Claude",reason:S.reason?` (${S.reason})`:""}):C("installCliPrompt",{tool:"Claude"})})]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:()=>B(!I),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] mr-1",children:I?"expand_less":"help"}),I?C("hide"):C("howToInstall")]})]}),I&&(0,s.jsxs)("div",{className:"p-4 bg-surface border border-border rounded-lg",children:[(0,s.jsx)("h4",{className:"font-medium mb-3",children:C("installationGuide")}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"text-text-muted mb-1",children:C("platforms")}),(0,s.jsx)("code",{className:"block px-3 py-2 bg-black/5 dark:bg-white/5 rounded font-mono text-xs",children:"npm install -g @anthropic-ai/claude-code"})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:[C("afterInstallationRun")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"claude"})," ",C("toVerify")]})]})]})]}),!A&&ea&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[S?.settings?.env?.ANTHROPIC_BASE_URL&&(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("current")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("span",{className:"flex-1 px-2 py-1.5 text-xs text-text-muted truncate",children:S.settings.env.ANTHROPIC_BASE_URL})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("baseUrl")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:(v=V||g).endsWith("/v1")?v:`${v}/v1`,onChange:e=>Y(e.target.value),placeholder:C("baseUrlPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),V&&V!==g&&(0,s.jsx)("button",{onClick:()=>Y(""),className:"p-1 text-text-muted hover:text-primary rounded transition-colors",title:C("resetToDefault"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"restart_alt"})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("apiKey")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),y.length>0?(0,s.jsx)("select",{value:L,onChange:e=>F(e.target.value),className:"flex-1 px-2 py-1.5 bg-surface rounded text-xs border border-border focus:outline-none focus:ring-1 focus:ring-primary/50",children:y.map(e=>(0,s.jsx)("option",{value:e.key,children:e.key},e.id))}):(0,s.jsx)("span",{className:"flex-1 text-xs text-text-muted px-2 py-1.5",children:b?C("noApiKeysCreateOne"):C("defaultOmnirouteKey")})]}),e.defaultModels.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:e.name}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:n[e.alias]||"",onChange:t=>m(e.alias,t.target.value),placeholder:C("providerModelPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),(0,s.jsx)("button",{onClick:()=>{$(e.alias),U(!0)},disabled:!f,className:`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${f?"bg-surface border-border text-text-main hover:border-primary cursor-pointer":"opacity-50 cursor-not-allowed border-border"}`,children:C("selectModel")}),n[e.alias]&&(0,s.jsx)("button",{onClick:()=>m(e.alias,""),className:"p-1 text-text-muted hover:text-red-500 rounded transition-colors",title:C("clear"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"close"})})]},e.alias))]}),R&&(0,s.jsxs)("div",{className:`flex items-center gap-2 px-2 py-1.5 rounded text-xs ${"success"===R.type?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"success"===R.type?"check_circle":"error"}),(0,s.jsx)("span",{children:R.text})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eo,disabled:!f,loading:T,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),C("apply")]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:ec,disabled:!S?.hasOmniRoute,loading:P,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"restore"}),C("reset")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>G(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"content_copy"}),C("manualConfig")]}),(0,s.jsx)("div",{className:"flex-1"}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{ee(!Z),Z||ed()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"history"}),C("backups"),X.length>0&&` (${X.length})`]})]}),Z&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"history"}),C("configBackups")]}),0===X.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:C("noBackupsYet")}):(0,s.jsx)("div",{className:"space-y-1.5",children:X.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"description"}),(0,s.jsx)("span",{className:"flex-1 truncate font-mono",title:e.id,children:e.id}),(0,s.jsx)("span",{className:"text-text-muted whitespace-nowrap",children:new Date(e.createdAt).toLocaleString()}),(0,s.jsx)("button",{onClick:()=>ex(e.id),disabled:et===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:et===e.id?"...":C("restore")})]},e.id))})]})]})]}),(0,s.jsx)(c.ModelSelectModal,{isOpen:K,onClose:()=>U(!1),onSelect:e=>{D&&m(D,e.value)},selectedModel:D?n[D]:null,activeProviders:i,modelAliases:H,title:C("selectModelForAlias",{alias:D||""})}),(0,s.jsx)(d.default,{isOpen:W,onClose:()=>G(!1),title:C("claudeManualConfiguration"),configs:(k=L&&L.trim()?L:b?"<API_KEY_FROM_DASHBOARD>":"sk_omniroute",w={ANTHROPIC_BASE_URL:en(),ANTHROPIC_AUTH_TOKEN:k},e.defaultModels.forEach(e=>{let t=n[e.alias];t&&e.envKey&&(w[e.envKey]=t)}),[{filename:"~/.claude/settings.json",content:JSON.stringify({env:w},null,2)}])})]})}var d=d;function f({tool:e,isExpanded:t,onToggle:r,baseUrl:i,apiKeys:n,activeProviders:m,cloudEnabled:h,batchStatus:g,lastConfiguredAt:f}){let y,b,j,N=(0,u.useTranslations)("cliTools"),[v,k]=(0,a.useState)(null),[w,C]=(0,a.useState)(!1),[S,_]=(0,a.useState)(!1),[A,O]=(0,a.useState)(!1),[T,E]=(0,a.useState)(null),[P,M]=(0,a.useState)(!1),[R,z]=(0,a.useState)(""),[I,B]=(0,a.useState)(""),[K,U]=(0,a.useState)(!1),[D,$]=(0,a.useState)({}),[L,F]=(0,a.useState)(!1),[H,J]=(0,a.useState)(""),[W,G]=(0,a.useState)([]),[V,Y]=(0,a.useState)(!1),[q,X]=(0,a.useState)(""),[Q,Z]=(0,a.useState)(!1),[ee,et]=(0,a.useState)(null),[es,ea]=(0,a.useState)([]),[el,er]=(0,a.useState)(!1),[ei,en]=(0,a.useState)(null),eo=!!(v?.installed&&v?.runnable);(0,a.useEffect)(()=>{n?.length>0&&!R&&z(n[0].key)},[n,R]),(0,a.useEffect)(()=>{t&&!v&&(em(),ec(),eh(),eb())},[t,v]);let ec=async()=>{try{let e=await fetch("/api/models/alias"),t=await e.json();e.ok&&$(t.aliases||{})}catch(e){console.log("Error fetching model aliases:",e)}};(0,a.useEffect)(()=>{if(v?.config){let e=v.config.match(/^model\s*=\s*"([^"]+)"/m);e&&B(e[1])}},[v]);let ed=(eo?v.config?v.config.includes(i)||v.config.includes("localhost")||v.config.includes("127.0.0.1")?"configured":"other":"not_configured":null)||g?.configStatus||null,ex=()=>{let e=H||`${i}/v1`;return e.endsWith("/v1")?e:`${e}/v1`},em=async()=>{C(!0);try{let e=await fetch("/api/cli-tools/codex-settings"),t=await e.json();k(t)}catch(e){k({installed:!1,error:e.message})}finally{C(!1)}},eu=async()=>{_(!0),E(null);try{let e=R&&R.trim()||h?R:"sk_omniroute",t=await fetch("/api/cli-tools/codex-settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({baseUrl:ex(),apiKey:e,model:I})}),s=await t.json();t.ok?(E({type:"success",text:N("settingsApplied")}),em()):E({type:"error",text:s.error||N("failedApplySettings")})}catch(e){E({type:"error",text:e.message})}finally{_(!1)}},ep=async()=>{O(!0),E(null);try{let e=await fetch("/api/cli-tools/codex-settings",{method:"DELETE"}),t=await e.json();e.ok?(E({type:"success",text:N("settingsReset")}),B(""),em()):E({type:"error",text:t.error||N("failedResetSettings")})}catch(e){E({type:"error",text:e.message})}finally{O(!1)}},eh=async()=>{try{let e=await fetch("/api/cli-tools/codex-profiles"),t=await e.json();e.ok&&G(t.profiles||[])}catch(e){console.log("Error fetching profiles:",e)}},eg=async()=>{if(q.trim()){Z(!0),E(null);try{let e=await fetch("/api/cli-tools/codex-profiles",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:q.trim()})}),t=await e.json();e.ok?(E({type:"success",text:N("profileSaved",{name:q})}),X(""),eh()):E({type:"error",text:t.error||N("failedSaveProfile")})}catch(e){E({type:"error",text:e.message})}finally{Z(!1)}}},ef=async e=>{et(e),E(null);try{let t=await fetch("/api/cli-tools/codex-profiles",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})}),s=await t.json();t.ok?(E({type:"success",text:s.message||N("profileActivated")}),em(),eb()):E({type:"error",text:s.error||N("failedActivateProfile")})}catch(e){E({type:"error",text:e.message})}finally{et(null)}},ey=async e=>{try{(await fetch("/api/cli-tools/codex-profiles",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})})).ok&&eh()}catch(e){console.log("Error deleting profile:",e)}},eb=async()=>{try{let e=await fetch("/api/cli-tools/backups?tool=codex"),t=await e.json();e.ok&&ea(t.backups||[])}catch(e){console.log("Error fetching backups:",e)}},ej=async e=>{en(e),E(null);try{let t=await fetch("/api/cli-tools/backups",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool:"codex",backupId:e})}),s=await t.json();t.ok?(E({type:"success",text:N("backupRestored")}),em(),eb()):E({type:"error",text:s.error||N("failedRestore")})}catch(e){E({type:"error",text:e.message})}finally{en(null)}};return(0,s.jsxs)(l.Card,{padding:"sm",className:"overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between hover:cursor-pointer",onClick:r,children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:(0,s.jsx)(x.default,{src:"/providers/codex.png",alt:e.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.currentTarget.style.display="none"}})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-medium text-sm",children:e.name}),(0,s.jsx)(p,{effectiveConfigStatus:ed,batchStatus:g,lastConfiguredAt:f})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted truncate",children:N("toolDescriptions.codex")})]})]}),(0,s.jsx)("span",{className:`material-symbols-outlined text-text-muted text-[20px] transition-transform ${t?"rotate-180":""}`,children:"expand_more"})]}),t&&(0,s.jsxs)("div",{className:"mt-4 pt-4 border-t border-border flex flex-col gap-4",children:[w&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin",children:"progress_activity"}),(0,s.jsx)("span",{children:N("checkingCli",{tool:"Codex"})})]}),!w&&v&&!eo&&(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-yellow-500",children:"warning"}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("p",{className:"font-medium text-yellow-600 dark:text-yellow-400",children:v.installed?N("cliNotRunnable",{tool:"Codex"}):N("cliNotInstalled",{tool:"Codex"})}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:v.installed?N("cliFoundFailedHealthcheck",{tool:"Codex",reason:v.reason?` (${v.reason})`:""}):N("installCodexPrompt")})]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:()=>M(!P),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] mr-1",children:P?"expand_less":"help"}),P?N("hide"):N("howToInstall")]})]}),P&&(0,s.jsxs)("div",{className:"p-4 bg-surface border border-border rounded-lg",children:[(0,s.jsx)("h4",{className:"font-medium mb-3",children:N("installationGuide")}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"text-text-muted mb-1",children:N("platforms")}),(0,s.jsx)("code",{className:"block px-3 py-2 bg-black/5 dark:bg-white/5 rounded font-mono text-xs",children:"npm install -g @openai/codex"})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:[N("afterInstallationRun")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"codex"})," ",N("toVerify")]}),(0,s.jsx)("div",{className:"pt-2 border-t border-border",children:(0,s.jsxs)("p",{className:"text-text-muted text-xs",children:[N("codexAuthNotePrefix")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"~/.codex/auth.json"})," ",N("codexAuthNoteMiddle")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"OPENAI_API_KEY"}),". ",N("codexAuthNoteSuffix")]})})]})]})]}),!w&&eo&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[v?.config&&((b=(y=v.config.match(/base_url\s*=\s*"([^"]+)"/))?y[1]:null)?(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("current")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("span",{className:"flex-1 px-2 py-1.5 text-xs text-text-muted truncate",children:b})]}):null),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("baseUrl")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:H||`${i}/v1`,onChange:e=>J(e.target.value),placeholder:N("baseUrlPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),H&&H!==`${i}/v1`&&(0,s.jsx)("button",{onClick:()=>J(""),className:"p-1 text-text-muted hover:text-primary rounded transition-colors",title:N("resetToDefault"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"restart_alt"})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("apiKey")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),n.length>0?(0,s.jsx)("select",{value:R,onChange:e=>z(e.target.value),className:"flex-1 px-2 py-1.5 bg-surface rounded text-xs border border-border focus:outline-none focus:ring-1 focus:ring-primary/50",children:n.map(e=>(0,s.jsx)("option",{value:e.key,children:e.key},e.id))}):(0,s.jsx)("span",{className:"flex-1 text-xs text-text-muted px-2 py-1.5",children:h?N("noApiKeysCreateOne"):N("defaultOmnirouteKey")})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("model")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:I,onChange:e=>B(e.target.value),placeholder:N("providerModelPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),(0,s.jsx)("button",{onClick:()=>U(!0),disabled:!m?.length,className:`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${m?.length?"bg-surface border-border text-text-main hover:border-primary cursor-pointer":"opacity-50 cursor-not-allowed border-border"}`,children:N("selectModel")}),I&&(0,s.jsx)("button",{onClick:()=>B(""),className:"p-1 text-text-muted hover:text-red-500 rounded transition-colors",title:N("clear"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"close"})})]})]}),T&&(0,s.jsxs)("div",{className:`flex items-center gap-2 px-2 py-1.5 rounded text-xs ${"success"===T.type?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"success"===T.type?"check_circle":"error"}),(0,s.jsx)("span",{children:T.text})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eu,disabled:!R||!I,loading:S,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),N("apply")]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:ep,disabled:!v.hasOmniRoute,loading:A,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"restore"}),N("reset")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>F(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"content_copy"}),N("manualConfig")]}),(0,s.jsx)("div",{className:"flex-1"}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{Y(!V),V||eh()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"manage_accounts"}),N("profiles")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{er(!el),el||eb()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"history"}),N("backups"),es.length>0&&` (${es.length})`]})]}),V&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"manage_accounts"}),N("savedProfiles")]}),0===W.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:N("noProfilesYet")}):(0,s.jsx)("div",{className:"space-y-1.5 mb-3",children:W.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"person"}),(0,s.jsx)("span",{className:"font-medium flex-1 truncate",children:e.name}),(0,s.jsx)("span",{className:"text-text-muted truncate max-w-[140px]",title:e.authLabel,children:e.authLabel}),(0,s.jsx)("button",{onClick:()=>ef(e.id),disabled:ee===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:ee===e.id?"...":N("activate")}),(0,s.jsx)("button",{onClick:()=>ey(e.id),className:"p-0.5 text-text-muted hover:text-red-500 transition-colors",title:N("deleteProfile"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"delete"})})]},e.id))}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("input",{type:"text",value:q,onChange:e=>X(e.target.value),placeholder:N("profileNamePlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50",onKeyDown:e=>"Enter"===e.key&&eg()}),(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eg,disabled:!q.trim(),loading:Q,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),N("saveCurrent")]})]})]}),el&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"history"}),N("configBackups")]}),0===es.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:N("noBackupsYet")}):(0,s.jsx)("div",{className:"space-y-1.5",children:es.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"description"}),(0,s.jsx)("span",{className:"flex-1 truncate font-mono",title:e.id,children:e.id}),(0,s.jsx)("span",{className:"text-text-muted whitespace-nowrap",children:new Date(e.createdAt).toLocaleString()}),(0,s.jsx)("button",{onClick:()=>ej(e.id),disabled:ei===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:ei===e.id?"...":N("restore")})]},e.id))})]})]})]}),(0,s.jsx)(c.ModelSelectModal,{isOpen:K,onClose:()=>U(!1),onSelect:e=>{B(e.value),U(!1)},selectedModel:I,activeProviders:m,modelAliases:D,title:N("selectModelForTool",{tool:"Codex"})}),(0,s.jsx)(d.default,{isOpen:L,onClose:()=>F(!1),title:N("codexManualConfiguration"),configs:(j=R&&R.trim()?R:h?"<API_KEY_FROM_DASHBOARD>":"sk_omniroute",[{filename:"~/.codex/config.toml",content:`# OmniRoute Configuration for Codex CLI
7
+ }`}},antigravity:{id:"antigravity",name:"Antigravity",image:"/providers/antigravity.png",color:"#4285F4",description:"Google Antigravity IDE with MITM",configType:"mitm",modelAliases:["claude-opus-4-6-thinking","claude-sonnet-4-6","gemini-3-flash","gpt-oss-120b-medium","gemini-3.1-pro-high","gemini-3.1-pro-low"],defaultModels:[{id:"gemini-3.1-pro-high",name:"Gemini 3.1 Pro High",alias:"gemini-3.1-pro-high"},{id:"gemini-3.1-pro-low",name:"Gemini 3.1 Pro Low",alias:"gemini-3.1-pro-low"},{id:"gemini-3-flash",name:"Gemini 3 Flash",alias:"gemini-3-flash"},{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6",alias:"claude-sonnet-4-6"},{id:"claude-opus-4-6-thinking",name:"Claude Opus 4.6 Thinking",alias:"claude-opus-4-6-thinking"},{id:"gpt-oss-120b-medium",name:"GPT OSS 120B Medium",alias:"gpt-oss-120b-medium"}]},copilot:{id:"copilot",name:"GitHub Copilot",image:"/providers/copilot.png",color:"#1F6FEB",description:"GitHub Copilot Chat — VS Code Extension",configType:"custom"},opencode:{id:"opencode",name:"OpenCode",image:"/providers/opencode.png",icon:"terminal",color:"#FF6B35",description:"OpenCode AI coding agent (Terminal)",configType:"guide",guideSteps:[{step:1,title:"Install OpenCode",desc:"Install via npm: npm install -g opencode-ai"},{step:2,title:"API Key",type:"apiKeySelector"},{step:3,title:"Set Base URL",desc:"opencode config set baseUrl {{baseUrl}}"},{step:4,title:"Select Model",type:"modelSelector"}]},kiro:{id:"kiro",name:"Kiro AI",image:"/providers/kiro.png",icon:"psychology_alt",color:"#FF6B35",description:"Amazon Kiro — AI-powered IDE with MITM",configType:"mitm",guideSteps:[{step:1,title:"Open Kiro Settings",desc:"Go to Settings → AI Provider"},{step:2,title:"Base URL",value:"{{baseUrl}}",copyable:!0},{step:3,title:"API Key",type:"apiKeySelector"},{step:4,title:"Select Model",type:"modelSelector"}]}};e.i(313705);var n=e.i(25230),o=e.i(474078),c=e.i(95368),d=e.i(193464),d=d,x=e.i(657688),m=e.i(861745),u=e.i(948148);function p({effectiveConfigStatus:e,batchStatus:t,lastConfiguredAt:a=null}){let l=(0,u.useTranslations)("cliTools"),r=(0,m.useLocale)(),i=e||t?.configStatus||null,n={configured:{dotClass:"bg-green-500",badgeClass:"bg-green-500/10 text-green-600 dark:text-green-400",text:l("configured")},not_configured:{dotClass:"bg-yellow-500",badgeClass:"bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",text:l("notConfigured")},not_installed:{dotClass:"bg-zinc-400 dark:bg-zinc-500",badgeClass:"bg-zinc-500/10 text-zinc-500 dark:text-zinc-400",text:l("notInstalled")},other:{dotClass:"bg-blue-500",badgeClass:"bg-blue-500/10 text-blue-600 dark:text-blue-400",text:l("custom")},unknown:{dotClass:"bg-zinc-400 dark:bg-zinc-500",badgeClass:"bg-zinc-500/10 text-zinc-500 dark:text-zinc-400",text:l("unknown")}},o=i?n[i]||n.unknown:null;return(0,s.jsxs)(s.Fragment,{children:[o&&(0,s.jsxs)("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 text-[11px] font-medium rounded-full ${o.badgeClass}`,children:[(0,s.jsx)("span",{className:`size-1.5 rounded-full ${o.dotClass}`}),o.text]}),a?(0,s.jsxs)("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] text-text-muted",title:l("lastSavedAt",{date:new Date(a).toLocaleString(r)}),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"schedule"}),function(e,t){let s=Date.now()-new Date(e).getTime();if(s<0)return t("justNow");let a=Math.floor(s/1e3);if(a<60)return t("justNow");let l=Math.floor(a/60);if(l<60)return t("minutesAgoShort",{count:l});let r=Math.floor(l/60);if(r<24)return t("hoursAgoShort",{count:r});let i=Math.floor(r/24);if(i<30)return t("daysAgoShort",{count:i});let n=Math.floor(i/30);return n<12?t("monthsAgoShort",{count:n}):t("yearsAgoShort",{count:Math.floor(n/12)})}(a,l)]}):i&&"not_installed"!==i?(0,s.jsxs)("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[12px]",children:"schedule"}),l("never")]}):null]})}let h=t.default.env.NEXT_PUBLIC_CLOUD_URL;function g({tool:e,isExpanded:t,onToggle:r,activeProviders:i,modelMappings:n,onModelMappingChange:m,baseUrl:g,hasActiveProviders:f,apiKeys:y,cloudEnabled:b,batchStatus:j,lastConfiguredAt:N}){let v,k,w,C=(0,u.useTranslations)("cliTools"),[S,_]=(0,a.useState)(null),[A,O]=(0,a.useState)(!1),[T,E]=(0,a.useState)(!1),[P,M]=(0,a.useState)(!1),[R,z]=(0,a.useState)(null),[I,B]=(0,a.useState)(!1),[K,U]=(0,a.useState)(!1),[D,$]=(0,a.useState)(null),[L,F]=(0,a.useState)(""),[H,J]=(0,a.useState)({}),[W,G]=(0,a.useState)(!1),[V,Y]=(0,a.useState)(""),q=(0,a.useRef)(!1),[X,Q]=(0,a.useState)([]),[Z,ee]=(0,a.useState)(!1),[et,es]=(0,a.useState)(null),ea=!!(S?.installed&&S?.runnable),el=(()=>{if(!ea)return null;let e=S.settings?.env?.ANTHROPIC_BASE_URL;if(!e)return"not_configured";let t=e.includes("localhost")||e.includes("127.0.0.1"),s=b&&h&&e.startsWith(h);return t||s?"configured":"other"})()||j?.configStatus||null;(0,a.useEffect)(()=>{y?.length>0&&!L&&F(y[0].key)},[y,L]),(0,a.useEffect)(()=>{t&&!S&&(ei(),er(),ed())},[t,S]);let er=async()=>{try{let e=await fetch("/api/models/alias"),t=await e.json();e.ok&&J(t.aliases||{})}catch(e){console.log("Error fetching model aliases:",e)}};(0,a.useEffect)(()=>{if(S?.installed&&!q.current){q.current=!0;let t=S.settings?.env||{};e.defaultModels.forEach(e=>{if(e.envKey){let s=t[e.envKey]||e.defaultValue||"";s&&m(e.alias,s)}});let s=t.ANTHROPIC_AUTH_TOKEN;s&&y?.some(e=>e.key===s)&&F(s)}},[S,y,e.defaultModels,m]);let ei=async()=>{O(!0);try{let e=await fetch("/api/cli-tools/claude-settings"),t=await e.json();_(t)}catch(e){_({installed:!1,error:e.message})}finally{O(!1)}},en=()=>{let e=V||g;return e.endsWith("/v1")?e:`${e}/v1`},eo=async()=>{E(!0),z(null);try{let t={ANTHROPIC_BASE_URL:en()},s=L?.trim()||(y?.length>0?y[0].key:null)||(b?null:"sk_omniroute");s&&(t.ANTHROPIC_AUTH_TOKEN=s),e.defaultModels.forEach(e=>{let s=n[e.alias];s&&e.envKey&&(t[e.envKey]=s)});let a=await fetch("/api/cli-tools/claude-settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({env:t})}),l=await a.json();a.ok?(z({type:"success",text:C("settingsApplied")}),_(e=>({...e,hasBackup:!0,settings:{...e?.settings,env:t}}))):z({type:"error",text:l.error||C("failedApplySettings")})}catch(e){z({type:"error",text:e.message})}finally{E(!1)}},ec=async()=>{M(!0),z(null);try{let t=await fetch("/api/cli-tools/claude-settings",{method:"DELETE"}),s=await t.json();t.ok?(z({type:"success",text:C("settingsReset")}),e.defaultModels.forEach(e=>m(e.alias,e.defaultValue||"")),F("")):z({type:"error",text:s.error||C("failedResetSettings")})}catch(e){z({type:"error",text:e.message})}finally{M(!1)}},ed=async()=>{try{let e=await fetch("/api/cli-tools/backups?tool=claude"),t=await e.json();e.ok&&Q(t.backups||[])}catch(e){console.log("Error fetching backups:",e)}},ex=async e=>{es(e),z(null);try{let t=await fetch("/api/cli-tools/backups",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool:"claude",backupId:e})}),s=await t.json();t.ok?(z({type:"success",text:C("backupRestored")}),ei(),ed()):z({type:"error",text:s.error||C("failedRestore")})}catch(e){z({type:"error",text:e.message})}finally{es(null)}};return(0,s.jsxs)(l.Card,{padding:"sm",className:"overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between hover:cursor-pointer",onClick:r,children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:(0,s.jsx)(x.default,{src:"/providers/claude.png",alt:e.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.currentTarget.style.display="none"}})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-medium text-sm",children:e.name}),(0,s.jsx)(p,{effectiveConfigStatus:el,batchStatus:j,lastConfiguredAt:N})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted truncate",children:C("toolDescriptions.claude")})]})]}),(0,s.jsx)("span",{className:`material-symbols-outlined text-text-muted text-[20px] transition-transform ${t?"rotate-180":""}`,children:"expand_more"})]}),t&&(0,s.jsxs)("div",{className:"mt-4 pt-4 border-t border-border flex flex-col gap-4",children:[A&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin",children:"progress_activity"}),(0,s.jsx)("span",{children:C("checkingCli",{tool:"Claude"})})]}),!A&&S&&!ea&&(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-yellow-500",children:"warning"}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("p",{className:"font-medium text-yellow-600 dark:text-yellow-400",children:S.installed?C("cliNotRunnable",{tool:"Claude"}):C("cliNotInstalled",{tool:"Claude"})}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:S.installed?C("cliFoundFailedHealthcheck",{tool:"Claude",reason:S.reason?` (${S.reason})`:""}):C("installCliPrompt",{tool:"Claude"})})]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:()=>B(!I),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] mr-1",children:I?"expand_less":"help"}),I?C("hide"):C("howToInstall")]})]}),I&&(0,s.jsxs)("div",{className:"p-4 bg-surface border border-border rounded-lg",children:[(0,s.jsx)("h4",{className:"font-medium mb-3",children:C("installationGuide")}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"text-text-muted mb-1",children:C("platforms")}),(0,s.jsx)("code",{className:"block px-3 py-2 bg-black/5 dark:bg-white/5 rounded font-mono text-xs",children:"npm install -g @anthropic-ai/claude-code"})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:[C("afterInstallationRun")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"claude"})," ",C("toVerify")]})]})]})]}),!A&&ea&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[S?.settings?.env?.ANTHROPIC_BASE_URL&&(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("current")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("span",{className:"flex-1 px-2 py-1.5 text-xs text-text-muted truncate",children:S.settings.env.ANTHROPIC_BASE_URL})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("baseUrl")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:(v=V||g).endsWith("/v1")?v:`${v}/v1`,onChange:e=>Y(e.target.value),placeholder:C("baseUrlPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),V&&V!==g&&(0,s.jsx)("button",{onClick:()=>Y(""),className:"p-1 text-text-muted hover:text-primary rounded transition-colors",title:C("resetToDefault"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"restart_alt"})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:C("apiKey")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),y.length>0?(0,s.jsx)("select",{value:L,onChange:e=>F(e.target.value),className:"flex-1 px-2 py-1.5 bg-surface rounded text-xs border border-border focus:outline-none focus:ring-1 focus:ring-primary/50",children:y.map(e=>(0,s.jsx)("option",{value:e.key,children:e.key},e.id))}):(0,s.jsx)("span",{className:"flex-1 text-xs text-text-muted px-2 py-1.5",children:b?C("noApiKeysCreateOne"):C("defaultOmnirouteKey")})]}),e.defaultModels.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:e.name}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:n[e.alias]||"",onChange:t=>m(e.alias,t.target.value),placeholder:C("providerModelPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),(0,s.jsx)("button",{onClick:()=>{$(e.alias),U(!0)},disabled:!f,className:`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${f?"bg-surface border-border text-text-main hover:border-primary cursor-pointer":"opacity-50 cursor-not-allowed border-border"}`,children:C("selectModel")}),n[e.alias]&&(0,s.jsx)("button",{onClick:()=>m(e.alias,""),className:"p-1 text-text-muted hover:text-red-500 rounded transition-colors",title:C("clear"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"close"})})]},e.alias))]}),R&&(0,s.jsxs)("div",{className:`flex items-center gap-2 px-2 py-1.5 rounded text-xs ${"success"===R.type?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"success"===R.type?"check_circle":"error"}),(0,s.jsx)("span",{children:R.text})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eo,disabled:!f,loading:T,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),C("apply")]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:ec,disabled:!S?.hasOmniRoute,loading:P,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"restore"}),C("reset")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>G(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"content_copy"}),C("manualConfig")]}),(0,s.jsx)("div",{className:"flex-1"}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{ee(!Z),Z||ed()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"history"}),C("backups"),X.length>0&&` (${X.length})`]})]}),Z&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"history"}),C("configBackups")]}),0===X.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:C("noBackupsYet")}):(0,s.jsx)("div",{className:"space-y-1.5",children:X.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"description"}),(0,s.jsx)("span",{className:"flex-1 truncate font-mono",title:e.id,children:e.id}),(0,s.jsx)("span",{className:"text-text-muted whitespace-nowrap",children:new Date(e.createdAt).toLocaleString()}),(0,s.jsx)("button",{onClick:()=>ex(e.id),disabled:et===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:et===e.id?"...":C("restore")})]},e.id))})]})]})]}),(0,s.jsx)(c.ModelSelectModal,{isOpen:K,onClose:()=>U(!1),onSelect:e=>{D&&m(D,e.value)},selectedModel:D?n[D]:null,activeProviders:i,modelAliases:H,title:C("selectModelForAlias",{alias:D||""})}),(0,s.jsx)(d.default,{isOpen:W,onClose:()=>G(!1),title:C("claudeManualConfiguration"),configs:(k=L&&L.trim()?L:b?"<API_KEY_FROM_DASHBOARD>":"sk_omniroute",w={ANTHROPIC_BASE_URL:en(),ANTHROPIC_AUTH_TOKEN:k},e.defaultModels.forEach(e=>{let t=n[e.alias];t&&e.envKey&&(w[e.envKey]=t)}),[{filename:"~/.claude/settings.json",content:JSON.stringify({env:w},null,2)}])})]})}var d=d;function f({tool:e,isExpanded:t,onToggle:r,baseUrl:i,apiKeys:n,activeProviders:m,cloudEnabled:h,batchStatus:g,lastConfiguredAt:f}){let y,b,j,N=(0,u.useTranslations)("cliTools"),[v,k]=(0,a.useState)(null),[w,C]=(0,a.useState)(!1),[S,_]=(0,a.useState)(!1),[A,O]=(0,a.useState)(!1),[T,E]=(0,a.useState)(null),[P,M]=(0,a.useState)(!1),[R,z]=(0,a.useState)(""),[I,B]=(0,a.useState)(""),[K,U]=(0,a.useState)(!1),[D,$]=(0,a.useState)({}),[L,F]=(0,a.useState)(!1),[H,J]=(0,a.useState)(""),[W,G]=(0,a.useState)([]),[V,Y]=(0,a.useState)(!1),[q,X]=(0,a.useState)(""),[Q,Z]=(0,a.useState)(!1),[ee,et]=(0,a.useState)(null),[es,ea]=(0,a.useState)([]),[el,er]=(0,a.useState)(!1),[ei,en]=(0,a.useState)(null),eo=!!(v?.installed&&v?.runnable);(0,a.useEffect)(()=>{n?.length>0&&!R&&z(n[0].key)},[n,R]),(0,a.useEffect)(()=>{t&&!v&&(em(),ec(),eh(),eb())},[t,v]);let ec=async()=>{try{let e=await fetch("/api/models/alias"),t=await e.json();e.ok&&$(t.aliases||{})}catch(e){console.log("Error fetching model aliases:",e)}};(0,a.useEffect)(()=>{if(v?.config){let e=v.config.match(/^model\s*=\s*"([^"]+)"/m);e&&B(e[1])}},[v]);let ed=(eo?v.config?v.config.includes(i)||v.config.includes("localhost")||v.config.includes("127.0.0.1")?"configured":"other":"not_configured":null)||g?.configStatus||null,ex=()=>{let e=H||`${i}/v1`;return e.endsWith("/v1")?e:`${e}/v1`},em=async()=>{C(!0);try{let e=await fetch("/api/cli-tools/codex-settings"),t=await e.json();k(t)}catch(e){k({installed:!1,error:e.message})}finally{C(!1)}},eu=async()=>{_(!0),E(null);try{let e=R&&R.trim()||h?R:"sk_omniroute",t=await fetch("/api/cli-tools/codex-settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({baseUrl:ex(),apiKey:e,model:I})}),s=await t.json();t.ok?(E({type:"success",text:N("settingsApplied")}),em()):E({type:"error",text:s.error||N("failedApplySettings")})}catch(e){E({type:"error",text:e.message})}finally{_(!1)}},ep=async()=>{O(!0),E(null);try{let e=await fetch("/api/cli-tools/codex-settings",{method:"DELETE"}),t=await e.json();e.ok?(E({type:"success",text:N("settingsReset")}),B(""),em()):E({type:"error",text:t.error||N("failedResetSettings")})}catch(e){E({type:"error",text:e.message})}finally{O(!1)}},eh=async()=>{try{let e=await fetch("/api/cli-tools/codex-profiles"),t=await e.json();e.ok&&G(t.profiles||[])}catch(e){console.log("Error fetching profiles:",e)}},eg=async()=>{if(q.trim()){Z(!0),E(null);try{let e=await fetch("/api/cli-tools/codex-profiles",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:q.trim()})}),t=await e.json();e.ok?(E({type:"success",text:N("profileSaved",{name:q})}),X(""),eh()):E({type:"error",text:t.error||N("failedSaveProfile")})}catch(e){E({type:"error",text:e.message})}finally{Z(!1)}}},ef=async e=>{et(e),E(null);try{let t=await fetch("/api/cli-tools/codex-profiles",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})}),s=await t.json();t.ok?(E({type:"success",text:s.message||N("profileActivated")}),em(),eb()):E({type:"error",text:s.error||N("failedActivateProfile")})}catch(e){E({type:"error",text:e.message})}finally{et(null)}},ey=async e=>{try{(await fetch("/api/cli-tools/codex-profiles",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({profileId:e})})).ok&&eh()}catch(e){console.log("Error deleting profile:",e)}},eb=async()=>{try{let e=await fetch("/api/cli-tools/backups?tool=codex"),t=await e.json();e.ok&&ea(t.backups||[])}catch(e){console.log("Error fetching backups:",e)}},ej=async e=>{en(e),E(null);try{let t=await fetch("/api/cli-tools/backups",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tool:"codex",backupId:e})}),s=await t.json();t.ok?(E({type:"success",text:N("backupRestored")}),em(),eb()):E({type:"error",text:s.error||N("failedRestore")})}catch(e){E({type:"error",text:e.message})}finally{en(null)}};return(0,s.jsxs)(l.Card,{padding:"sm",className:"overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between hover:cursor-pointer",onClick:r,children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("div",{className:"size-8 flex items-center justify-center shrink-0",children:(0,s.jsx)(x.default,{src:"/providers/codex.png",alt:e.name,width:32,height:32,className:"size-8 object-contain rounded-lg",sizes:"32px",onError:e=>{e.currentTarget.style.display="none"}})}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h3",{className:"font-medium text-sm",children:e.name}),(0,s.jsx)(p,{effectiveConfigStatus:ed,batchStatus:g,lastConfiguredAt:f})]}),(0,s.jsx)("p",{className:"text-xs text-text-muted truncate",children:N("toolDescriptions.codex")})]})]}),(0,s.jsx)("span",{className:`material-symbols-outlined text-text-muted text-[20px] transition-transform ${t?"rotate-180":""}`,children:"expand_more"})]}),t&&(0,s.jsxs)("div",{className:"mt-4 pt-4 border-t border-border flex flex-col gap-4",children:[w&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-text-muted",children:[(0,s.jsx)("span",{className:"material-symbols-outlined animate-spin",children:"progress_activity"}),(0,s.jsx)("span",{children:N("checkingCli",{tool:"Codex"})})]}),!w&&v&&!eo&&(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-yellow-500",children:"warning"}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("p",{className:"font-medium text-yellow-600 dark:text-yellow-400",children:v.installed?N("cliNotRunnable",{tool:"Codex"}):N("cliNotInstalled",{tool:"Codex"})}),(0,s.jsx)("p",{className:"text-sm text-text-muted",children:v.installed?N("cliFoundFailedHealthcheck",{tool:"Codex",reason:v.reason?` (${v.reason})`:""}):N("installCodexPrompt")})]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:()=>M(!P),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[18px] mr-1",children:P?"expand_less":"help"}),P?N("hide"):N("howToInstall")]})]}),P&&(0,s.jsxs)("div",{className:"p-4 bg-surface border border-border rounded-lg",children:[(0,s.jsx)("h4",{className:"font-medium mb-3",children:N("installationGuide")}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{className:"text-text-muted mb-1",children:N("platforms")}),(0,s.jsx)("code",{className:"block px-3 py-2 bg-black/5 dark:bg-white/5 rounded font-mono text-xs",children:"npm install -g @openai/codex"})]}),(0,s.jsxs)("p",{className:"text-text-muted",children:[N("afterInstallationRun")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"codex"})," ",N("toVerify")]}),(0,s.jsx)("div",{className:"pt-2 border-t border-border",children:(0,s.jsxs)("p",{className:"text-text-muted text-xs",children:[N("codexAuthNotePrefix")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"~/.codex/auth.json"})," ",N("codexAuthNoteMiddle")," ",(0,s.jsx)("code",{className:"px-1 bg-black/5 dark:bg-white/5 rounded",children:"OPENAI_API_KEY"}),". ",N("codexAuthNoteSuffix")]})})]})]})]}),!w&&eo&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[v?.config&&((b=(y=v.config.match(/base_url\s*=\s*"([^"]+)"/))?y[1]:null)?(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("current")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("span",{className:"flex-1 px-2 py-1.5 text-xs text-text-muted truncate",children:b})]}):null),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("baseUrl")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:H||`${i}/v1`,onChange:e=>J(e.target.value),placeholder:N("baseUrlPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),H&&H!==`${i}/v1`&&(0,s.jsx)("button",{onClick:()=>J(""),className:"p-1 text-text-muted hover:text-primary rounded transition-colors",title:N("resetToDefault"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"restart_alt"})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("apiKey")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),n.length>0?(0,s.jsx)("select",{value:R,onChange:e=>z(e.target.value),className:"flex-1 px-2 py-1.5 bg-surface rounded text-xs border border-border focus:outline-none focus:ring-1 focus:ring-primary/50",children:n.map(e=>(0,s.jsx)("option",{value:e.key,children:e.key},e.id))}):(0,s.jsx)("span",{className:"flex-1 text-xs text-text-muted px-2 py-1.5",children:h?N("noApiKeysCreateOne"):N("defaultOmnirouteKey")})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"w-32 shrink-0 text-sm font-semibold text-text-main text-right",children:N("model")}),(0,s.jsx)("span",{className:"material-symbols-outlined text-text-muted text-[14px]",children:"arrow_forward"}),(0,s.jsx)("input",{type:"text",value:I,onChange:e=>B(e.target.value),placeholder:N("providerModelPlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"}),(0,s.jsx)("button",{onClick:()=>U(!0),disabled:!m?.length,className:`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${m?.length?"bg-surface border-border text-text-main hover:border-primary cursor-pointer":"opacity-50 cursor-not-allowed border-border"}`,children:N("selectModel")}),I&&(0,s.jsx)("button",{onClick:()=>B(""),className:"p-1 text-text-muted hover:text-red-500 rounded transition-colors",title:N("clear"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"close"})})]})]}),T&&(0,s.jsxs)("div",{className:`flex items-center gap-2 px-2 py-1.5 rounded text-xs ${"success"===T.type?"bg-green-500/10 text-green-600":"bg-red-500/10 text-red-600"}`,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"success"===T.type?"check_circle":"error"}),(0,s.jsx)("span",{children:T.text})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eu,disabled:!R||!I,loading:S,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),N("apply")]}),(0,s.jsxs)(o.Button,{variant:"outline",size:"sm",onClick:ep,disabled:!v.hasOmniRoute,loading:A,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"restore"}),N("reset")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>F(!0),children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"content_copy"}),N("manualConfig")]}),(0,s.jsx)("div",{className:"flex-1"}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{Y(!V),V||eh()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"manage_accounts"}),N("profiles")]}),(0,s.jsxs)(o.Button,{variant:"ghost",size:"sm",onClick:()=>{er(!el),el||eb()},children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"history"}),N("backups"),es.length>0&&` (${es.length})`]})]}),V&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"manage_accounts"}),N("savedProfiles")]}),0===W.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:N("noProfilesYet")}):(0,s.jsx)("div",{className:"space-y-1.5 mb-3",children:W.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"person"}),(0,s.jsx)("span",{className:"font-medium flex-1 truncate",children:e.name}),(0,s.jsx)("span",{className:"text-text-muted truncate max-w-[140px]",title:e.authLabel,children:e.authLabel}),(0,s.jsx)("button",{onClick:()=>ef(e.id),disabled:ee===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:ee===e.id?"...":N("activate")}),(0,s.jsx)("button",{onClick:()=>ey(e.id),className:"p-0.5 text-text-muted hover:text-red-500 transition-colors",title:N("deleteProfile"),children:(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"delete"})})]},e.id))}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("input",{type:"text",value:q,onChange:e=>X(e.target.value),placeholder:N("profileNamePlaceholder"),className:"flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50",onKeyDown:e=>"Enter"===e.key&&eg()}),(0,s.jsxs)(o.Button,{variant:"primary",size:"sm",onClick:eg,disabled:!q.trim(),loading:Q,children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] mr-1",children:"save"}),N("saveCurrent")]})]})]}),el&&(0,s.jsxs)("div",{className:"mt-2 p-3 bg-surface border border-border rounded-lg",children:[(0,s.jsxs)("h4",{className:"text-xs font-semibold text-text-main mb-2 flex items-center gap-1",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px]",children:"history"}),N("configBackups")]}),0===es.length?(0,s.jsx)("p",{className:"text-xs text-text-muted",children:N("noBackupsYet")}):(0,s.jsx)("div",{className:"space-y-1.5",children:es.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-black/5 dark:bg-white/5 rounded text-xs",children:[(0,s.jsx)("span",{className:"material-symbols-outlined text-[14px] text-text-muted",children:"description"}),(0,s.jsx)("span",{className:"flex-1 truncate font-mono",title:e.id,children:e.id}),(0,s.jsx)("span",{className:"text-text-muted whitespace-nowrap",children:new Date(e.createdAt).toLocaleString()}),(0,s.jsx)("button",{onClick:()=>ej(e.id),disabled:ei===e.id,className:"px-2 py-0.5 bg-primary/10 text-primary rounded text-[10px] font-medium hover:bg-primary/20 transition-colors disabled:opacity-50",children:ei===e.id?"...":N("restore")})]},e.id))})]})]})]}),(0,s.jsx)(c.ModelSelectModal,{isOpen:K,onClose:()=>U(!1),onSelect:e=>{B(e.value),U(!1)},selectedModel:I,activeProviders:m,modelAliases:D,title:N("selectModelForTool",{tool:"Codex"})}),(0,s.jsx)(d.default,{isOpen:L,onClose:()=>F(!1),title:N("codexManualConfiguration"),configs:(j=R&&R.trim()?R:h?"<API_KEY_FROM_DASHBOARD>":"sk_omniroute",[{filename:"~/.codex/config.toml",content:`# OmniRoute Configuration for Codex CLI
8
8
  model = "${I}"
9
9
  model_provider = "omniroute"
10
10
 
package/app/CHANGELOG.md CHANGED
@@ -4,6 +4,30 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## [2.8.5] — 2026-03-19
8
+
9
+ > Sprint: Fix zombie SSE streams, context cache first-turn, KIRO MITM, and triage 5 external issues.
10
+
11
+ ### Bug Fixes
12
+
13
+ - **Zombie SSE Streams** (#473): Reduce `STREAM_IDLE_TIMEOUT_MS` from 300s → 120s for faster combo fallback when providers hang mid-stream. Configurable via env var.
14
+ - **Context Cache Tag** (#474): Fix `injectModelTag()` to handle first-turn requests (no assistant messages) — context cache protection now works from the very first response.
15
+ - **KIRO MITM** (#481): Change KIRO `configType` from `guide` → `mitm` so the dashboard renders MITM Start/Stop controls.
16
+ - **E2E Test** (CI): Fix `providers-bailian-coding-plan.spec.ts` — dismiss pre-existing modal overlay before clicking Add API Key button.
17
+
18
+ ### Closed Issues
19
+
20
+ - #473 — Zombie SSE streams bypass combo fallback
21
+ - #474 — Context cache `<omniModel>` tag missing on first turn
22
+ - #481 — MITM for KIRO not activatable from dashboard
23
+ - #468 — Gemini CLI remote server (superseded by #462 deprecation)
24
+ - #438 — Claude unable to write files (external CLI issue)
25
+ - #439 — AppImage doesn't work (documented libfuse2 workaround)
26
+ - #402 — ARM64 DMG "damaged" (documented xattr -cr workaround)
27
+ - #460 — CLI not runnable on Windows (documented PATH fix)
28
+
29
+ ---
30
+
7
31
  ## [2.8.4] — 2026-03-19
8
32
 
9
33
  > Sprint: Gemini CLI deprecation, VM guide i18n fix, dependabot security fix, provider schema expansion.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OmniRoute API
4
- version: 2.8.4
4
+ version: 2.8.5
5
5
  description: |
6
6
  OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
7
7
  endpoint that routes requests to multiple AI providers with load balancing,
@@ -4,9 +4,9 @@ import { loadProviderCredentials } from "./credentialLoader.ts";
4
4
  export const FETCH_TIMEOUT_MS = parseInt(process.env.FETCH_TIMEOUT_MS || "120000", 10);
5
5
 
6
6
  // Idle timeout for SSE streams (ms). Closes stream if no data for this duration.
7
- // Default: 300s to support extended-thinking models (claude-opus-4-6, o3, etc.)
8
- // that may pause for >60s during deep reasoning phases. Override with STREAM_IDLE_TIMEOUT_MS env var.
9
- export const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.STREAM_IDLE_TIMEOUT_MS || "300000", 10);
7
+ // Default: 120s balances deep-reasoning pauses with fast zombie stream detection (#473).
8
+ // Extended-thinking models rarely pause >90s between chunks. Override with STREAM_IDLE_TIMEOUT_MS env var.
9
+ export const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.STREAM_IDLE_TIMEOUT_MS || "120000", 10);
10
10
 
11
11
  // Provider configurations
12
12
  // OAuth credentials read from env vars with hardcoded fallbacks for backward compatibility.
@@ -52,7 +52,15 @@ export function injectModelTag(messages: Message[], providerModel: string): Mess
52
52
 
53
53
  // Find last assistant message with string content
54
54
  const lastAssistantIdx = cleaned.map((m) => m.role).lastIndexOf("assistant");
55
- if (lastAssistantIdx === -1) return cleaned;
55
+
56
+ // #474: If no assistant message exists yet (first turn), append a synthetic one
57
+ // so the tag is present when the client sends the next request with the response.
58
+ if (lastAssistantIdx === -1) {
59
+ return [
60
+ ...cleaned,
61
+ { role: "assistant", content: `\n<omniModel>${providerModel}</omniModel>` },
62
+ ];
63
+ }
56
64
 
57
65
  const msg = cleaned[lastAssistantIdx];
58
66
  if (typeof msg.content !== "string") return cleaned;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.8.4",
3
+ "version": "2.8.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omniroute",
9
- "version": "2.8.4",
9
+ "version": "2.8.5",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "workspaces": [
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.8.4",
3
+ "version": "2.8.5",
4
4
  "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -193,8 +193,8 @@ export const CLI_TOOLS = {
193
193
  image: "/providers/kiro.png",
194
194
  icon: "psychology_alt",
195
195
  color: "#FF6B35",
196
- description: "Amazon Kiro — AI-powered IDE",
197
- configType: "guide",
196
+ description: "Amazon Kiro — AI-powered IDE with MITM",
197
+ configType: "mitm",
198
198
  guideSteps: [
199
199
  { step: 1, title: "Open Kiro Settings", desc: "Go to Settings → AI Provider" },
200
200
  { step: 2, title: "Base URL", value: "{{baseUrl}}", copyable: true },
@@ -63,6 +63,13 @@ test.describe("Bailian Coding Plan Provider", () => {
63
63
  const redirectedToLogin = page.url().includes("/login");
64
64
  test.skip(redirectedToLogin, "Authentication enabled without a login fixture.");
65
65
 
66
+ // Dismiss any pre-existing dialog/overlay that may appear on page load
67
+ const preExistingDialog = page.getByRole("dialog").first();
68
+ if (await preExistingDialog.isVisible({ timeout: 2000 }).catch(() => false)) {
69
+ await page.keyboard.press("Escape");
70
+ await preExistingDialog.waitFor({ state: "hidden", timeout: 3000 }).catch(() => {});
71
+ }
72
+
66
73
  const addKeyButton = page.getByRole("button", {
67
74
  name: /add.*api.*key|add.*key|add.*connection|connect/i,
68
75
  });
@@ -175,6 +182,13 @@ test.describe("Bailian Coding Plan Provider", () => {
175
182
  const redirectedToLogin = page.url().includes("/login");
176
183
  test.skip(redirectedToLogin, "Authentication enabled without a login fixture.");
177
184
 
185
+ // Dismiss any pre-existing dialog/overlay that may appear on page load
186
+ const preExistingDialog = page.getByRole("dialog").first();
187
+ if (await preExistingDialog.isVisible({ timeout: 2000 }).catch(() => false)) {
188
+ await page.keyboard.press("Escape");
189
+ await preExistingDialog.waitFor({ state: "hidden", timeout: 3000 }).catch(() => {});
190
+ }
191
+
178
192
  const addKeyButton = page.getByRole("button", {
179
193
  name: /add.*api.*key|add.*key|add.*connection|connect/i,
180
194
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "2.8.4",
3
+ "version": "2.8.5",
4
4
  "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
5
5
  "type": "module",
6
6
  "bin": {