@bitkyc08/opencodex 2.7.33 → 2.7.34

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 (64) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +21 -10
  4. package/README.ru.md +1 -1
  5. package/README.zh-CN.md +1 -1
  6. package/gui/dist/assets/index-BkmJJgg6.js +52 -0
  7. package/gui/dist/assets/index-Sg-7L_oZ.css +1 -0
  8. package/gui/dist/index.html +2 -2
  9. package/package.json +1 -1
  10. package/src/adapters/anthropic.ts +13 -6
  11. package/src/adapters/cursor/discovery.ts +39 -4
  12. package/src/adapters/cursor/exec-policy.ts +11 -13
  13. package/src/adapters/cursor/live-transport.ts +22 -4
  14. package/src/adapters/cursor/protobuf-events.ts +140 -8
  15. package/src/adapters/cursor/protobuf-request.ts +15 -0
  16. package/src/adapters/cursor/request-builder.ts +10 -5
  17. package/src/adapters/cursor/transport.ts +3 -2
  18. package/src/adapters/cursor/types.ts +14 -0
  19. package/src/adapters/kiro-constants.ts +12 -0
  20. package/src/adapters/kiro-errors.ts +111 -2
  21. package/src/adapters/kiro-events.ts +154 -35
  22. package/src/adapters/kiro-retry.ts +116 -32
  23. package/src/adapters/kiro-tools.ts +30 -20
  24. package/src/adapters/kiro-wire.ts +47 -6
  25. package/src/adapters/kiro.ts +891 -228
  26. package/src/adapters/openai-chat.ts +12 -5
  27. package/src/adapters/openai-responses.ts +7 -2
  28. package/src/bridge.ts +109 -26
  29. package/src/claude/outbound.ts +27 -4
  30. package/src/cli/index.ts +1 -1
  31. package/src/codex/catalog.ts +375 -33
  32. package/src/combos/index.ts +3 -0
  33. package/src/combos/request.ts +4 -4
  34. package/src/combos/resolve.ts +2 -2
  35. package/src/combos/types.ts +104 -2
  36. package/src/config.ts +70 -1
  37. package/src/lib/eventstream-decoder.ts +9 -0
  38. package/src/oauth/index.ts +3 -1
  39. package/src/oauth/kiro-credentials.ts +48 -20
  40. package/src/oauth/login-cli.ts +2 -0
  41. package/src/providers/derive.ts +8 -0
  42. package/src/providers/kiro-models.ts +2 -2
  43. package/src/providers/openai-sidecar.ts +28 -1
  44. package/src/providers/registry.ts +39 -2
  45. package/src/responses/parser.ts +22 -10
  46. package/src/responses/schema.ts +1 -0
  47. package/src/responses/state.ts +50 -10
  48. package/src/router.ts +15 -3
  49. package/src/server/auth-cors.ts +7 -0
  50. package/src/server/claude-messages.ts +6 -0
  51. package/src/server/index.ts +6 -3
  52. package/src/server/management-api.ts +187 -43
  53. package/src/server/ports.ts +4 -2
  54. package/src/server/request-log.ts +3 -2
  55. package/src/server/responses-item-id-repair.ts +281 -0
  56. package/src/server/responses.ts +274 -73
  57. package/src/types.ts +109 -16
  58. package/src/update/job.ts +81 -1
  59. package/src/vision/describe.ts +2 -1
  60. package/src/web-search/executor.ts +2 -1
  61. package/src/web-search/loop.ts +9 -1
  62. package/src/web-search/progress-stream.ts +12 -10
  63. package/gui/dist/assets/index-D6Fcl4yM.css +0 -1
  64. package/gui/dist/assets/index-d63HMU0x.js +0 -52
@@ -0,0 +1 @@
1
+ .provider-catalog{flex-direction:column;gap:10px;display:flex}.provider-catalog-tabs{border-bottom:1px solid var(--border);gap:4px;display:flex}.provider-catalog-tab{appearance:none;color:var(--muted);font:inherit;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;padding:8px 12px}.provider-catalog-tab.active{color:var(--fg);border-bottom-color:var(--accent)}.provider-catalog-accounts-hint{padding:2px 2px 0}.provider-catalog-search{width:100%}.provider-catalog-rows{flex-direction:column;gap:6px;max-height:360px;display:flex;overflow-y:auto}.provider-catalog-badges{flex-shrink:0;align-items:center;gap:4px;display:flex}.provider-catalog-empty{padding:8px}.provider-catalog-account-row .sub{text-overflow:ellipsis;overflow:hidden}.provider-catalog-footer{align-items:center;gap:8px;display:flex}.bar-warn{background:linear-gradient(90deg, var(--green), var(--amber))}.quota-row--warn .quota-label{color:var(--amber)}.quota-val--warn{color:var(--amber);align-items:center;gap:3px;display:inline-flex}.quota-stacked{flex-direction:column;gap:10px;display:flex}.quota-stacked-row{flex-direction:column;gap:4px;display:flex}.quota-stacked-head{justify-content:space-between;align-items:baseline;gap:8px;display:flex}.quota-stacked-limit{font-weight:600}.quota-stacked-reset{font-size:12px}.quota-stacked-bar-row{align-items:center;gap:8px;display:flex}.quota-stacked-bar{flex:1}.quota-stacked-used{font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px}.quota-stacked-used--warn{color:var(--amber)}.quota-stacked-limit-reached{color:var(--amber);align-items:center;gap:4px;font-size:12px;display:inline-flex}.main-inner:has(.pws-shell-container){max-width:1440px}.pws-shell-container{width:100%;min-width:0;container:provider-workspace/inline-size}.pws-root{gap:var(--space-4);grid-template-columns:minmax(240px,280px) minmax(0,1fr);width:100%;max-width:100%;min-height:480px;display:grid}.pws-rail{gap:var(--space-3);border-right:1px solid var(--border);padding-right:var(--space-3);flex-direction:column;min-width:0;display:flex}.pws-search-row{align-items:center;gap:6px;display:flex}.pws-search-wrap{flex:1;min-width:0;position:relative}.pws-search-icon{color:var(--muted);pointer-events:none;position:absolute;top:50%;left:8px;transform:translateY(-50%)}.pws-search-wrap .pws-search-input{width:100%;padding-left:32px}.pws-filter-wrap{position:relative}.pws-filter-btn{appearance:none;border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;color:var(--muted);min-width:var(--control-md);min-height:var(--control-md);background:0 0;padding:6px;position:relative}.pws-filter-btn--active{color:var(--text);border-color:var(--text)}.pws-filter-dot{background:var(--accent);border-radius:50%;width:6px;height:6px;position:absolute;top:3px;right:3px}.pws-filter-menu{z-index:30;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);flex-direction:column;gap:4px;min-width:230px;padding:10px;display:flex;position:absolute;top:calc(100% + 6px);right:0;box-shadow:0 8px 24px #0000001f}.pws-filter-title{margin-bottom:2px;font-weight:600}.pws-filter-head{text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin-top:8px;font-size:11px}.pws-filter-option{cursor:pointer;align-items:center;gap:8px;padding:3px 2px;display:flex}.pws-filter-label{flex:1}.pws-filter-count{color:var(--muted);font-variant-numeric:tabular-nums;font-size:12px}.pws-sort-grid{grid-template-columns:1fr 1fr;gap:4px;display:grid}.pws-sort-btn{appearance:none;border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;color:var(--muted);background:0 0;padding:4px 8px;font-size:12px}.pws-sort-btn--active{color:var(--text);border-color:var(--text)}.pws-filter-footer{justify-content:flex-end;margin-top:8px;display:flex}.pws-rail-list{flex-direction:column;gap:4px;min-height:0;display:flex;overflow-y:auto}.pws-rail-empty{padding:8px 4px;font-size:12px}.pws-rail-group{flex-direction:column;gap:2px;display:flex}.pws-rail-group-head{justify-content:space-between;align-items:center;gap:var(--space-2);font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--muted);padding:var(--space-2) var(--space-2) var(--space-1);display:flex}.pws-rail-group-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.pws-rail-group-count{font-variant-numeric:tabular-nums;flex-shrink:0}.providers-workspace-rail-row{grid-template-columns:var(--icon-lg) minmax(0, 1fr) max-content;align-items:center;gap:var(--space-2);width:100%;min-height:var(--pws-rail-row-height,46px);appearance:none;border-radius:var(--radius-sm);padding:var(--space-1-5) var(--space-2);cursor:pointer;text-align:left;color:inherit;font:inherit;transition:background var(--motion-fast), box-shadow var(--motion-fast);background:0 0;border:none;display:grid;overflow:hidden}.providers-workspace-rail-row:hover{background:var(--surface)}.providers-workspace-rail-row--selected{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--border)}.providers-workspace-rail-icon{width:var(--icon-lg);height:var(--icon-lg);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.providers-workspace-rail-icon img,.providers-workspace-rail-icon .provider-icon-mask{width:var(--icon-lg);height:var(--icon-lg);display:block}.provider-icon-mask{-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.providers-workspace-rail-copy{gap:var(--space-0-5);flex-direction:column;min-width:0;display:flex;overflow:hidden}.providers-workspace-rail-primary{align-items:center;gap:var(--space-1-5);min-width:0;display:flex}.providers-workspace-rail-name-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-size:var(--text-body);font-weight:var(--weight-medium);line-height:var(--leading-ui);overflow:hidden}.providers-workspace-rail-secondary{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-size:var(--text-caption);line-height:var(--leading-ui);color:var(--muted);overflow:hidden}.pwi-rail-badge{border:1px solid var(--border);color:var(--muted);border-radius:999px;padding:1px 6px;font-size:10px}.pwi-rail-badge--free{color:var(--green);border-color:var(--green)}.pwi-rail-badge--local{color:var(--amber);border-color:var(--amber)}.providers-workspace-rail-trail{flex-shrink:0;align-items:center;gap:4px;display:inline-flex}.pwi-default-star{color:var(--amber);display:inline-flex}.providers-workspace-rail-status{border-radius:50%;width:8px;height:8px;display:inline-block}.providers-workspace-rail-status--active{background:var(--green)}.providers-workspace-rail-status--warning{background:var(--amber)}.providers-workspace-rail-status--inactive{background:var(--muted)}.pws-main{min-width:0;max-width:100%;padding:0 var(--space-2);overflow:hidden}.pws-detail-placeholder{flex-direction:column;align-items:flex-start;gap:8px;padding:24px 8px;display:flex}.pws-empty-root{justify-content:center;padding:48px 16px;display:flex}.pws-empty-hero{text-align:center;flex-direction:column;align-items:center;gap:16px;max-width:640px;display:flex}.pws-empty-tiles{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;width:100%;display:grid}.pws-empty-tile{appearance:none;border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;color:inherit;font:inherit;background:0 0;flex-direction:column;align-items:center;gap:6px;padding:14px 12px;display:flex}.pws-empty-tile:hover{background:var(--surface)}.pws-empty-tile-label{font-weight:600}.pws-empty-tile-desc{font-size:12px}@container provider-workspace (width<=920px){.pws-root{gap:var(--space-3);grid-template-columns:240px minmax(0,1fr)}}@container provider-workspace (width<=680px){.pws-root{grid-template-columns:minmax(0,1fr);min-height:auto}.pws-rail{--pws-rail-row-height:var(--control-touch);border-right:none;border-bottom:1px solid var(--border);padding-right:0;padding-bottom:var(--space-3);max-height:320px;overflow-y:auto}.pws-main{padding:var(--space-2) 0 0}}@media (width<=768px){.pws-root{grid-template-columns:1fr;min-height:auto}.pws-rail{border-right:none;border-bottom:1px solid var(--border);max-height:320px;padding-bottom:12px;padding-right:0;overflow-y:auto}.pws-main{padding-top:8px}.pws-empty-tiles{grid-template-columns:1fr}}@media (width<=360px){.main-inner:has(.pws-shell-container)>.page-head{flex-wrap:wrap;align-items:flex-start}.main-inner:has(.pws-shell-container)>.page-head .row{flex-wrap:wrap;justify-content:flex-start;width:100%}}.pws-detail-back-link{color:var(--accent,#3b82f6);font:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;margin-bottom:8px;padding:0;font-size:.82rem;display:inline-flex}.pws-detail-back-link:hover{text-decoration:underline}.pws-detail-back-chevron{width:12px;height:12px;transform:rotate(180deg)}.pws-detail-head-main{align-items:center;gap:10px;margin-bottom:12px;display:flex}.pws-detail-head-main .pws-detail-title{align-items:center;gap:8px;display:flex}.pws-detail-actions{align-items:center;gap:8px;margin-left:auto;display:flex}.pws-detail-toggle{align-items:center;gap:6px;display:flex}.pws-detail-toggle-label{color:var(--muted);font-size:.82rem}.btn-icon-only{padding:4px 6px}.pws-overview-layout{grid-template-columns:1fr 280px;align-items:start;gap:24px;display:grid}.pws-overview-main{flex-direction:column;gap:20px;min-width:0;display:flex}.pws-overview-sidebar{flex-direction:column;align-self:start;gap:20px;display:flex}@container provider-workspace (width<=920px){.pws-overview-layout{grid-template-columns:minmax(0,1fr)}}.pws-auth-summary{align-items:center;gap:8px;font-size:.88rem;display:flex}.pws-auth-summary--warn{border:1px solid color-mix(in srgb, var(--yellow,#eab308) 45%, transparent);background:color-mix(in srgb, var(--yellow,#eab308) 12%, transparent);color:inherit;border-radius:8px;align-items:flex-start;padding:10px 12px}.pws-auth-summary-body{flex-wrap:wrap;flex:1;align-items:center;gap:8px 10px;min-width:0;display:flex}.pws-auth-summary--warn svg{color:var(--yellow,#eab308);flex-shrink:0;margin-top:2px}.pws-auth-dot{background:var(--green,#22c55e);border-radius:50%;flex-shrink:0;width:8px;height:8px}.pws-notes-section{min-width:0}.pws-notes-display{text-align:left;width:100%;font:inherit;color:inherit;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;min-height:48px;padding:8px 10px;font-size:.85rem;transition:border-color .15s;display:block}.pws-notes-display:hover{border-color:var(--border)}.pws-notes-textarea{border:1px solid var(--accent,#3b82f6);width:100%;font:inherit;color:inherit;background:var(--bg);resize:vertical;border-radius:6px;min-height:48px;padding:8px 10px;font-size:.85rem}.pws-notes-textarea:focus{outline:none;box-shadow:0 0 0 2px #3b82f640}@media (width<=768px){.pws-overview-layout{grid-template-columns:1fr}.pws-overview-sidebar{position:static}}.pws-detail{flex-direction:column;gap:0;width:100%;min-width:0;max-width:960px;display:flex}.pws-detail-icon{flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;display:flex}.pws-detail-icon img,.pws-detail-icon .provider-icon-mask{width:28px;height:28px}.pws-detail-title-wrap{flex:1;min-width:0}.pws-detail-title{margin:0;font-size:1.15rem;font-weight:600;line-height:1.3}.pws-detail-tabs{scrollbar-width:thin;border-bottom:1px solid var(--border);gap:0;margin-top:8px;margin-bottom:16px;display:flex;overflow-x:auto}.pws-detail-tab{appearance:none;font:inherit;color:var(--muted);cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;padding:8px 14px;font-size:.82rem;font-weight:500;transition:color .15s,border-color .15s}.pws-detail-tab:hover{color:var(--text)}.pws-detail-tab--active{color:var(--text);border-bottom-color:var(--text)}.pws-detail-tab:focus-visible{outline:2px solid var(--accent-ring);outline-offset:-2px}.pws-detail-panel:focus{outline:none}.pws-section{margin-bottom:16px}.pws-section-title{text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin:0 0 8px;font-size:.7rem;font-weight:600}.pws-section--side{margin-bottom:12px}.pws-kv{flex-direction:column;gap:0;margin:0;display:flex}.pws-kv-row{gap:12px;padding:5px 0;font-size:.84rem;line-height:1.4;display:flex}.pws-kv-row dt{width:130px;color:var(--muted);flex-shrink:0;font-weight:400}.pws-kv-row dd{word-break:break-word;flex:1;min-width:0;margin:0}.pws-kv-row dd code{font-size:.8rem}.pws-kv-mono{font-variant-numeric:tabular-nums}.pws-status-ok{color:var(--green,#22c55e);align-items:center;gap:4px;display:flex}.pws-status-warn{color:var(--amber,#f59e0b);align-items:center;gap:4px;display:flex}.pws-stats-note{margin-top:6px;font-size:.75rem}.pws-edit-settings-link,.pws-view-usage-link{margin-top:8px;font-size:.8rem}.pws-section-head{justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:12px;display:flex}.pws-section-head .pws-section-title{margin-bottom:0}.pws-model-search{width:100%;margin-bottom:18px}.pws-model-list{flex-wrap:wrap;align-items:center;gap:12px;margin-top:4px;display:flex}.pws-model-chip{border:1px solid color-mix(in oklab, var(--border) 85%, transparent);background:color-mix(in oklab, var(--surface,var(--panel)) 92%, var(--text) 4%);border-radius:8px;align-items:center;gap:10px;max-width:100%;padding:8px 10px 8px 12px;display:inline-flex}.pws-model-chip-main{min-width:0;color:inherit;font:inherit;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;margin:0;padding:0;display:inline-flex}.pws-model-chip-main:hover .pws-model-id{color:var(--accent,var(--text))}.pws-model-chip-main:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px;border-radius:4px}.pws-model-id{font-family:var(--mono,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);color:var(--text);white-space:nowrap;font-size:.8rem;font-weight:600;line-height:1.35}.pws-model-flag{flex-shrink:0}.pws-inline-error{align-items:center;gap:10px;margin-top:8px;display:flex}.pws-usage-block+.pws-usage-block{border-top:1px solid color-mix(in oklab, var(--border) 45%, transparent);margin-top:32px;padding-top:24px}.pws-usage-metrics{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 28px;margin-top:14px;display:grid}.pws-usage-metric{flex-direction:column;gap:8px;min-width:0;display:flex}.pws-usage-metric-value{font-variant-numeric:tabular-nums;letter-spacing:-.02em;color:var(--text);font-size:1.35rem;font-weight:650;line-height:1.15}.pws-usage-metric-label{font-size:.8rem;line-height:1.3}.pws-usage-meta{margin-top:16px}.pws-usage-metrics-3{grid-template-columns:repeat(3,minmax(0,1fr))}.pws-cost-disclaimer{margin-top:8px;font-size:.75rem}.pws-model-table{border-collapse:collapse;width:100%;font-size:.8rem}.pws-model-table th{text-align:left;border-bottom:1px solid var(--border);padding:6px 8px;font-weight:600}.pws-model-table td{border-bottom:1px solid var(--border-faint,#8080801a);padding:6px 8px}.pws-model-table .num{text-align:right;font-variant-numeric:tabular-nums}.pws-model-table .mono{font-family:var(--font-mono,monospace);font-size:.78rem}.pws-model-row:hover{background:var(--bg-subtle,#8080800d)}.pws-share-bar{background:var(--border-faint,#80808026);border-radius:3px;min-width:60px;height:6px}.pws-share-bar-fill{background:var(--green,#22c55e);border-radius:3px;height:100%}.pws-model-detail{background:var(--bg-subtle,#8080800d)}.pws-model-detail td{padding:8px 8px 8px 24px}.pws-model-detail-grid{grid-template-columns:repeat(2,1fr);gap:8px 24px;font-size:.8rem;display:grid}@media (width<=600px){.pws-usage-metrics-3{grid-template-columns:1fr}}@media (width<=640px){.pws-usage-metrics{grid-template-columns:1fr;gap:16px}}.pwi-auth-section{flex-direction:column;gap:12px;display:flex}.pwi-auth-body{flex-direction:column;gap:10px;display:flex}.pwi-auth-status-row{align-items:center;gap:8px;display:flex}.pwi-auth-dot{border-radius:var(--radius-round);background:var(--muted);flex-shrink:0;width:8px;height:8px}.pwi-auth-dot--ok{background:var(--green)}.pwi-auth-dot--off{background:var(--muted)}.pwi-auth-dot--warn{background:var(--amber)}.pwi-auth-status-text{font-size:var(--text-control);color:var(--text)}.pwi-auth-state{min-height:36px;font-size:var(--text-label);color:var(--muted);background:var(--raised);border-radius:var(--radius-xs);align-items:center;gap:8px;padding:8px 10px;display:flex}.pwi-auth-state--error{color:var(--red);background:var(--red-soft);justify-content:space-between}.pwi-auth-state--empty{justify-content:center}.pwi-auth-actions{flex-wrap:wrap;gap:8px;display:flex}.pwi-auth-wait{flex-direction:column;gap:6px;display:flex}.pwi-auth-wait-title{font-size:var(--text-control);color:var(--text);font-weight:600}.pwi-auth-wait-copy{font-size:var(--text-label);color:var(--muted);line-height:1.45}.pwi-device-code-wrap{border:1px solid var(--border);background:var(--surface);border-radius:10px;flex-wrap:wrap;align-items:center;gap:10px;margin:6px 0;padding:12px;display:flex}.pwi-device-code{letter-spacing:.14em;color:var(--text);-webkit-user-select:all;user-select:all;font-size:20px;font-weight:800}.pwi-auth-row-copy{flex-direction:column;align-items:flex-start;gap:2px;min-width:0;display:flex}.pwi-auth-row-secondary{text-overflow:ellipsis;max-width:100%;font-size:var(--text-label);color:var(--muted);overflow:hidden}.pwi-auth-open-link{font-size:var(--text-label);color:var(--accent);cursor:pointer;text-decoration:underline}.pwi-auth-list{flex-direction:column;gap:4px;display:flex}.pwi-auth-row{border-radius:var(--radius-xs);transition:background var(--motion-fast);align-items:center;gap:8px;padding:6px 8px;display:flex}.pwi-auth-row:hover{background:var(--hover)}.pwi-auth-row--active{background:var(--accent-soft)}.pwi-auth-row-main{appearance:none;min-width:0;color:inherit;text-align:left;cursor:pointer;border-radius:var(--radius-2xs);background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:2px;display:flex}.pwi-auth-row-main:disabled{cursor:default;opacity:.72}.pwi-auth-row-main:focus-visible,.pwi-auth-row-remove:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px}.pwi-auth-row-label{font-size:var(--text-control);color:var(--text);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.pwi-auth-row-remove{cursor:pointer;color:var(--muted);border-radius:var(--radius-2xs);transition:color var(--motion-fast), background var(--motion-fast);background:0 0;border:none;padding:2px}.pwi-auth-row-remove:hover{color:var(--red);background:var(--red-soft)}.pwi-auth-add-key{font-size:var(--text-label);color:var(--accent);cursor:pointer;text-align:left;background:0 0;border:none;padding:4px 0}.pwi-auth-add-key:hover{text-decoration:underline}@keyframes pwi-spin{to{transform:rotate(360deg)}}.pwi-spin-inline{border:2px solid var(--border);border-top-color:var(--accent);border-radius:var(--radius-round);width:14px;height:14px;animation:.7s linear infinite pwi-spin;display:inline-block}.pwi-settings-form{flex-direction:column;gap:14px;display:flex;position:relative}.pwi-settings-field{flex-direction:column;gap:4px;display:flex}.pwi-settings-label{font-size:var(--text-label);color:var(--muted);letter-spacing:.01em;font-weight:500}.pwi-settings-textarea{width:100%;min-height:60px;font:inherit;font-size:var(--text-control);color:var(--text);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-xs);resize:vertical;transition:border-color var(--motion-fast);padding:8px 10px}.pwi-settings-textarea:focus{border-color:var(--accent-ring);outline:none}.pwi-settings-hint{font-size:var(--text-caption);color:var(--muted);line-height:1.4}.pwi-settings-sticky-bar{z-index:2;background:var(--bg);border-top:1px solid var(--border-soft);align-items:center;gap:8px;padding:10px 0;display:flex;position:sticky;bottom:0}.pwi-settings-sticky-bar-actions{gap:8px;margin-left:auto;display:flex}.pwi-settings-msg{font-size:var(--text-label);border-radius:var(--radius-xs);padding:6px 10px;line-height:1.4}.pwi-settings-msg--ok{background:var(--green-soft);color:var(--green)}.pwi-settings-msg--err{background:var(--red-soft);color:var(--red)}.pwi-settings-dirty{font-size:var(--text-caption);color:var(--amber)}.pwi-json-panel{flex-direction:column;gap:8px;display:flex}.pwi-json-panel-header{justify-content:space-between;align-items:center;gap:8px;display:flex}.pwi-json-panel-title{font-size:var(--text-control);color:var(--text);font-weight:600}.pwi-json-panel-actions{gap:6px;display:flex}.pwi-json-panel-desc{font-size:var(--text-caption);color:var(--muted);line-height:1.4}.pwi-json-textarea{width:100%;min-height:180px;font-family:ui-monospace,SF Mono,Cascadia Code,Segoe UI Mono,Menlo,monospace;font-size:var(--text-label);tab-size:2;color:var(--text);background:var(--raised);border:1px solid var(--border);border-radius:var(--radius-xs);resize:vertical;transition:border-color var(--motion-fast);padding:10px 12px;line-height:1.5}.pwi-json-textarea:focus{border-color:var(--accent-ring);outline:none}.dialog-backdrop{z-index:900;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);width:90%;max-width:420px;box-shadow:var(--shadow);flex-direction:column;gap:16px;padding:24px;display:flex}.dialog-actions{justify-content:flex-end;gap:8px;display:flex}.pws-dashboard{flex-direction:column;gap:14px;max-width:100%;padding:4px 0;display:flex}.pws-dashboard-header{flex-direction:row;justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.pws-dashboard-header-text{flex-direction:column;gap:2px;min-width:0;display:flex}.pws-dashboard-title{margin:0;font-size:1.1rem;font-weight:600}.pws-dashboard-subtitle{margin:0;font-size:.82rem}.pws-dashboard-summary{gap:10px;display:flex}.pws-dashboard-card{border:1px solid var(--border);background:var(--bg-secondary,var(--bg));border-radius:8px;flex-direction:column;align-items:center;gap:2px;min-width:80px;padding:10px 20px;display:flex}.pws-dashboard-card-count{font-size:1.25rem;font-weight:700;line-height:1}.pws-dashboard-card--ok .pws-dashboard-card-count{color:var(--green,#22c55e)}.pws-dashboard-card--warn .pws-dashboard-card-count{color:var(--yellow,#eab308)}.pws-dashboard-card--muted .pws-dashboard-card-count{color:var(--fg-muted,#888)}.pws-dashboard-card-label{color:var(--fg-muted,#888);letter-spacing:.02em;font-size:.7rem}.pws-dashboard-columns{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);align-items:start;gap:20px;display:grid}.pws-dashboard-section{flex-direction:column;gap:4px;min-width:0;display:flex}.pws-dashboard-section-title{text-transform:uppercase;letter-spacing:.04em;color:var(--fg-muted,#888);margin:0;padding-bottom:2px;font-size:.68rem;font-weight:600}.pws-dashboard-attention .pws-dashboard-section-title{color:var(--yellow,#eab308);text-transform:none;letter-spacing:0;align-items:center;gap:6px;font-size:.82rem;display:inline-flex}.pws-dashboard-row--attention{border-color:color-mix(in srgb, var(--yellow,#eab308) 40%, var(--border));background:color-mix(in srgb, var(--yellow,#eab308) 8%, var(--bg-secondary,var(--bg)))}.pws-dashboard-rows{flex-direction:column;gap:0;display:flex}.pws-dashboard-row{cursor:pointer;text-align:left;color:inherit;font:inherit;background:0 0;border:none;border-radius:6px;grid-template-columns:22px 1fr auto auto;align-items:center;gap:8px;width:100%;padding:6px;transition:background .12s;display:grid}.pws-dashboard-row:hover{background:var(--bg-hover,#80808014)}.pws-dashboard-row-icon{justify-content:center;align-items:center;width:20px;height:20px;display:flex}.pws-dashboard-row-icon img,.pws-dashboard-row-icon .provider-icon-mask{width:18px;height:18px}.pws-dashboard-row-info{flex-direction:column;gap:1px;min-width:0;display:flex}.pws-dashboard-row-name{white-space:nowrap;text-overflow:ellipsis;font-size:.85rem;font-weight:500;overflow:hidden}.pws-dashboard-row-meta{font-size:.72rem}.pws-dashboard-row-count{white-space:nowrap;font-size:.8rem}.pws-dashboard-row-chevron{width:12px;height:12px;color:var(--fg-muted,#888);flex-shrink:0}.pws-dashboard-row-bars{grid-column:1/-1;padding-top:1px;padding-left:30px}@container provider-workspace (width<=920px){.pws-dashboard-columns{grid-template-columns:1fr;gap:14px}}@media (width<=900px){.pws-dashboard-columns{grid-template-columns:1fr;gap:14px}}@media (width<=600px){.pws-dashboard-summary{flex-direction:column}.pws-dashboard-card{flex-direction:row;justify-content:space-between;min-width:0}}.combos-workspace-root{grid-template-columns:minmax(340px,28vw) 1fr;align-items:stretch;width:100%;height:100%;min-height:100%;display:grid;overflow:hidden}.combos-workspace-shell{flex-direction:column;width:100%;height:100%;min-height:0;display:flex;overflow:hidden}.combos-workspace-shell-banner{flex-shrink:0;padding:10px 16px 0}.combos-workspace-shell-body{flex-direction:column;flex:auto;min-height:0;display:flex;overflow:hidden}.combos-workspace-rail{border-right:1px solid var(--border);background:var(--rail);flex-direction:column;height:100%;min-height:0;display:flex;position:sticky;top:0;overflow-y:auto}.combos-workspace-rail-header{border-bottom:1px solid var(--border-soft);flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;padding:14px 16px 12px;display:flex}.combos-workspace-rail-title{color:var(--text);font-size:18px;font-weight:600}.combos-workspace-rail-count{font-family:var(--mono);color:var(--faint);font-size:11px}.combos-workspace-rail-list{flex-direction:column;flex:auto;display:flex;overflow-y:auto}.combos-workspace-rail-group+.combos-workspace-rail-group{margin-top:10px}.combos-workspace-rail-group-head{color:var(--muted);align-items:center;gap:7px;padding:8px 16px 6px;font-size:11.5px;font-weight:600;display:flex}.combos-workspace-rail-row{border:none;border-bottom:1px solid var(--border-soft);cursor:pointer;min-height:40px;font:inherit;color:var(--text);text-align:left;background:0 0;grid-template-columns:26px minmax(0,1fr) 3.5rem 14px;align-items:center;column-gap:8px;width:100%;padding:11px 12px 11px 14px;font-size:13px;transition:background .12s;display:grid}.combos-workspace-rail-row:hover{background:var(--hover)}.combos-workspace-rail-row.combos-workspace-rail-row--selected{background:var(--accent-soft);box-shadow:inset 3px 0 0 var(--accent)}.combos-workspace-rail-row:focus-visible{outline:1px solid var(--accent);outline-offset:-1px}.combos-workspace-rail-icon{width:26px;height:26px;color:var(--text);flex-shrink:0;justify-content:center;align-items:center;display:flex}.combos-workspace-rail-name{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--mono);font-size:12.5px;overflow:hidden}.combos-workspace-rail-meta{font-family:var(--mono);color:var(--faint);text-align:right;font-size:11px}.combos-workspace-rail-chevron{width:14px;height:14px;color:var(--faint)}.combos-workspace-main{background:var(--bg);flex-direction:column;min-width:0;height:100%;min-height:0;display:flex;overflow:hidden}.combos-workspace-overview,.combos-workspace-detail{flex:auto;min-height:0;padding:20px 24px 32px;overflow-y:auto}.combos-workspace-empty-root{justify-content:center;align-items:center;height:100%;min-height:100%;display:flex}.cwi-empty-cta{appearance:none;border:1px solid color-mix(in srgb, var(--border,var(--text)) 55%, transparent);background:color-mix(in srgb, var(--surface,transparent) 40%, transparent);width:100%;max-width:44ch;font:inherit;text-align:center;color:inherit;cursor:pointer;border-radius:10px;flex-direction:column;justify-content:center;align-items:center;gap:10px;margin:0;padding:40px 28px;transition:border-color .15s,background-color .15s,box-shadow .15s;display:flex}.cwi-empty-cta-title{color:var(--text);font-size:20px;font-weight:650;transition:color .15s}.cwi-empty-cta .pwi-empty-right-icon{transition:color .15s}.cwi-empty-cta:hover{border-color:color-mix(in srgb, var(--accent,var(--text)) 35%, var(--border,var(--text)));background:color-mix(in srgb, var(--accent,var(--text)) 6%, transparent);box-shadow:0 0 0 1px color-mix(in srgb, var(--accent,var(--text)) 12%, transparent)}.cwi-empty-cta:hover .pwi-empty-right-icon{color:var(--muted)}.cwi-empty-cta:hover .cwi-empty-cta-title{color:var(--accent,var(--text))}.cwi-empty-cta:focus-visible{outline:2px solid color-mix(in srgb, var(--accent,var(--text)) 45%, transparent);outline-offset:3px}.combos-workspace-overview-head{justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:16px;display:flex}.combos-workspace-overview-title{margin:0;font-size:20px;font-weight:600}.combos-workspace-detail-head{border-bottom:1px solid var(--border-soft);flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;display:flex}.combos-workspace-detail-title{font-size:18px;font-weight:600;font-family:var(--mono);min-width:0;margin:0}.combos-workspace-detail-actions{flex-wrap:wrap;align-items:center;gap:8px;margin-left:auto;display:flex}.combos-workspace-tabs{border-bottom:1px solid var(--border-soft);gap:4px;margin-bottom:16px;display:flex}.combos-workspace-tab{appearance:none;font:inherit;color:var(--muted);cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:8px 12px;font-size:13px;font-weight:500}.combos-workspace-tab:hover{color:var(--text)}.combos-workspace-tab.combos-workspace-tab--active{color:var(--text);border-bottom-color:var(--accent)}.combos-workspace-tab-content{flex-direction:column;gap:16px;max-width:720px;display:flex}.cwi-search-row{border-bottom:1px solid var(--border-soft);flex-shrink:0;align-items:center;gap:8px;padding:10px 14px 12px;display:flex}.cwi-search-wrap{flex:1;min-width:0;position:relative}.cwi-search-wrap .cwi-search-icon{width:14px;height:14px;color:var(--faint);pointer-events:none;position:absolute;top:50%;left:10px;transform:translateY(-50%)}.cwi-search-input{width:100%;padding-left:32px!important}.cwi-count-strip{flex-wrap:wrap;gap:10px;margin-bottom:18px;display:flex}.cwi-count-pill{border:1px solid var(--border-soft);border-radius:var(--radius);background:var(--raised);align-items:baseline;gap:6px;padding:8px 12px;display:inline-flex}.cwi-count-pill strong{font-family:var(--mono);font-size:16px}.cwi-count-pill span{color:var(--muted);font-size:12px}.cwi-target-list{flex-direction:column;gap:8px;display:flex}.cwi-target-row{grid-template-columns:28px minmax(0,1fr) minmax(0,1.2fr) 4.5rem auto;align-items:center;gap:8px;display:grid}.cwi-target-row--failover{grid-template-columns:28px minmax(0,1fr) minmax(0,1.2fr) auto}.cwi-target-row--dragging{opacity:.55}.cwi-target-row--drop{box-shadow:inset 0 0 0 1px var(--accent);border-radius:var(--radius)}.cwi-target-grip{border-radius:var(--radius);width:28px;height:32px;color:var(--faint);cursor:grab;touch-action:none;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.cwi-target-grip:hover{color:var(--muted);background:var(--hover)}.cwi-target-grip:active{cursor:grabbing}.cwi-target-actions{flex-shrink:0;gap:2px;display:flex}.cwi-strategy-seg{border-radius:var(--radius-pill);background:var(--surface-soft,var(--raised));gap:2px;padding:3px;display:inline-flex}.cwi-strategy-seg .btn{border-radius:var(--radius-pill);border:none;min-width:88px;padding:5px 12px}.cwi-strategy-seg .btn-ghost{color:var(--muted);background:0 0}.cwi-copy-chip{font-family:var(--mono);cursor:pointer;font-size:12px}.cwi-form-grid{flex-direction:column;gap:12px;display:flex}.cwi-field label{color:var(--muted);margin-bottom:4px;font-size:12px;font-weight:600;display:block}.cwi-field .input,.cwi-field select.input{width:100%}.cwi-attention-list{flex-direction:column;gap:0;display:flex}.cwi-attention-row{border:none;border-bottom:1px solid var(--border-soft);width:100%;font:inherit;color:var(--text);text-align:left;cursor:pointer;background:0 0;align-items:center;gap:10px;padding:10px 0;display:flex}.cwi-attention-row:hover{color:var(--accent)}.cwi-modal-form{flex-direction:column;gap:14px;max-height:min(70vh,560px);padding-right:2px;display:flex;overflow-y:auto}.cwi-modal-actions{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}@media (width<=939px){.combos-workspace-root{grid-template-rows:minmax(220px,38vh) 1fr;grid-template-columns:1fr}.combos-workspace-rail{border-right:none;border-bottom:1px solid var(--border);position:relative}.cwi-target-row,.cwi-target-row--failover{grid-template-columns:28px 1fr auto}.cwi-target-row>.input:nth-child(2),.cwi-target-row>.input:nth-child(3){grid-column:2/-1}}.pwi-dot{background:var(--muted);border-radius:50%;flex-shrink:0;width:7px;height:7px;display:inline-block}.pwi-back-overview{white-space:nowrap;flex:none;gap:4px;margin-right:2px}.pwi-section{background:0 0;border:none;border-radius:0;min-width:0;padding:0}.pwi-section-title{color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin:0 0 4px;font-size:12px;font-weight:650}.pwi-empty-right-icon{color:var(--faint)}.pwi-empty-right-sub{color:var(--muted);max-width:44ch;margin:0;font-size:13.5px;line-height:1.5}.pwi-json-unsaved-card,.pwi-remove-confirm-card{width:min(420px,92vw);max-width:420px;padding:20px 22px 16px}.pwi-json-unsaved-title,.pwi-remove-confirm-title{color:var(--text);margin:0 0 8px;font-size:16px;font-weight:650}.pwi-json-unsaved-desc,.pwi-remove-confirm-desc{margin:0 0 18px;font-size:13.5px;line-height:1.45}.pwi-json-unsaved-actions,.pwi-remove-confirm-actions{flex-wrap:wrap;justify-content:flex-end;gap:8px;display:flex}.pwi-remove-confirm-danger{background:var(--red)!important;color:#fff!important;border-color:#0000!important}.pwi-remove-confirm-danger:hover:not(:disabled){filter:brightness(1.08)}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;--bg:var(--lightningcss-light,#fff)var(--lightningcss-dark,#212121);--rail:var(--lightningcss-light,#f9f9f9)var(--lightningcss-dark,#171717);--surface:var(--lightningcss-light,#fff)var(--lightningcss-dark,#262626);--raised:var(--lightningcss-light,#f4f4f4)var(--lightningcss-dark,#303030);--raised-hover:var(--lightningcss-light,#ececec)var(--lightningcss-dark,#3a3a3a);--border:var(--lightningcss-light,#e6e6e6)var(--lightningcss-dark,#3d3d3d);--border-soft:var(--lightningcss-light,#f0f0f0)var(--lightningcss-dark,#333);--hover:var(--lightningcss-light,#0d0d0d08)var(--lightningcss-dark,#ffffff08);--text:var(--lightningcss-light,#0d0d0d)var(--lightningcss-dark,#ececec);--muted:var(--lightningcss-light,#6e6e6e)var(--lightningcss-dark,#a6a6a6);--faint:var(--lightningcss-light,#707070)var(--lightningcss-dark,#9a9a9a);--accent:var(--lightningcss-light,#0d0d0d)var(--lightningcss-dark,#ececec);--accent-hover:var(--lightningcss-light,#3d3d3d)var(--lightningcss-dark,#fff);--accent-ink:var(--lightningcss-light,#fff)var(--lightningcss-dark,#0d0d0d);--accent-soft:var(--lightningcss-light,#0d0d0d0f)var(--lightningcss-dark,#ffffff17);--accent-ring:var(--lightningcss-light,#0d0d0d4d)var(--lightningcss-dark,#ffffff61);--green:var(--lightningcss-light,#0a7d5c)var(--lightningcss-dark,#4ecb9d);--green-soft:var(--lightningcss-light,#10a37f1a)var(--lightningcss-dark,#4ecb9d21);--red:var(--lightningcss-light,#b91c1c)var(--lightningcss-dark,#f87171);--red-soft:var(--lightningcss-light,#b91c1c17)var(--lightningcss-dark,#f8717121);--amber:var(--lightningcss-light,#9a4a08)var(--lightningcss-dark,#fbbf24);--amber-soft:var(--lightningcss-light,#b453091a)var(--lightningcss-dark,#fbbf2421);--space-0-5:2px;--space-1:4px;--space-1-5:6px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;--space-10:40px;--space-12:48px;--space-16:64px;--radius-2xs:4px;--radius:12px;--radius-sm:8px;--radius-xs:6px;--radius-lg:16px;--radius-round:50%;--radius-pill:999px;--font-ui:"OpenAI Sans", "Pretendard Variable", Pretendard, "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;--font-code:ui-monospace, "SFMono-Regular", "Cascadia Code", "JetBrains Mono", "Noto Sans Mono CJK KR", Menlo, Consolas, monospace;--font:var(--font-ui);--mono:var(--font-code);--text-micro:10px;--text-caption:11px;--text-label:12px;--text-control:13px;--text-body:14px;--text-subtitle:16px;--text-title:20px;--text-display:24px;--weight-regular:400;--weight-medium:500;--weight-semibold:600;--weight-bold:700;--leading-tight:1.2;--leading-ui:1.35;--leading-body:1.5;--leading-relaxed:1.6;--tracking-normal:0;--tracking-wide:.04em;--control-sm:28px;--control-md:34px;--control-lg:40px;--control-touch:44px;--icon-sm:14px;--icon-md:16px;--icon-lg:20px;--motion-fast:.12s;--motion-normal:.18s;--z-sticky:20;--z-overlay:30;--z-popover:40;--z-modal:50;--shadow:0 1px 2px var(--lightningcss-light,#1018280f)var(--lightningcss-dark,#00000080), 0 10px 28px var(--lightningcss-light,#10182812)var(--lightningcss-dark,#0000004d);--shadow-sm:0 1px 2px var(--lightningcss-light,#1018280f)var(--lightningcss-dark,#0006);--toggle-w:36px;--toggle-h:20px;--toggle-dot:14px;--toggle-off-bg:var(--lightningcss-light,#d4d4d4)var(--lightningcss-dark,#4a4a4a);--toggle-on-bg:var(--lightningcss-light,#0d0d0d)var(--lightningcss-dark,#4ecb9d);--toggle-dot-color:var(--lightningcss-light,#fff)var(--lightningcss-dark,#0d0d0d)}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root{--glass-rail:var(--lightningcss-light,#f9f9f9a8)var(--lightningcss-dark,#1717179e);--glass-panel:var(--lightningcss-light,#ffffffc7)var(--lightningcss-dark,#262626d1);--glass-blur:saturate(1.6) blur(22px)}*{box-sizing:border-box}html,body,#root{height:100%}html{background:var(--bg);overflow-x:hidden}body{color:var(--text);font-family:var(--font-ui);font-size:var(--text-body);line-height:var(--leading-body);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;background:0 0;margin:0;overflow-x:hidden}body:before{content:"";z-index:-1;pointer-events:none;filter:blur(70px);background:radial-gradient(42% 38% at 12% 6%,var(--lightningcss-light,#a4c4ff6b)var(--lightningcss-dark,#6082c829),#0000 70%),radial-gradient(46% 42% at 88% 18%,var(--lightningcss-light,#a8e2c561)var(--lightningcss-dark,#58a08221),#0000 70%),radial-gradient(40% 36% at 70% 92%,var(--lightningcss-light,#ffe0c24d)var(--lightningcss-dark,#b48c6414),#0000 72%);position:fixed;inset:-20%}a{color:var(--text);text-decoration:underline;-webkit-text-decoration-color:var(--faint);text-decoration-color:var(--faint);text-underline-offset:2px}a:hover{-webkit-text-decoration-color:var(--text);text-decoration-color:var(--text)}code{font-family:var(--font-code);font-size:var(--text-label)}.mono{font-family:var(--font-code);font-variant-numeric:tabular-nums}h1,h2,h3,h4{font-weight:var(--weight-semibold);letter-spacing:0;line-height:var(--leading-tight);margin:0}.text-micro{line-height:var(--leading-ui);font-size:var(--text-micro)!important}.text-caption{line-height:var(--leading-ui);font-size:var(--text-caption)!important}.text-label{line-height:var(--leading-ui);font-size:var(--text-label)!important}.text-control{line-height:var(--leading-ui);font-size:var(--text-control)!important}.text-body{line-height:var(--leading-body);font-size:var(--text-body)!important}.text-subtitle{line-height:var(--leading-tight);font-size:var(--text-subtitle)!important}.text-title{line-height:var(--leading-tight);font-size:var(--text-title)!important}.text-display{line-height:var(--leading-tight);font-size:var(--text-display)!important}.font-regular{font-weight:var(--weight-regular)!important}.font-medium{font-weight:var(--weight-medium)!important}.font-semibold{font-weight:var(--weight-semibold)!important}.font-bold{font-weight:var(--weight-bold)!important}.leading-tight{line-height:var(--leading-tight)!important}.leading-ui{line-height:var(--leading-ui)!important}.leading-body{line-height:var(--leading-body)!important}.leading-relaxed{line-height:var(--leading-relaxed)!important}::selection{background:var(--accent-soft)}input[type=checkbox],input[type=radio]{accent-color:var(--accent)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-pill);border:2px solid var(--bg)}::-webkit-scrollbar-thumb:hover{background:var(--faint)}:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px;border-radius:var(--radius-2xs)}.app{grid-template-columns:232px 1fr;min-height:100dvh;display:grid}.sidebar{height:100dvh;z-index:var(--z-overlay);border-right:1px solid var(--border);background:var(--glass-rail);-webkit-backdrop-filter:var(--glass-blur);flex-direction:column;align-self:start;gap:4px;padding:18px 14px;display:flex;position:sticky;top:0}.brand{align-items:center;gap:10px;padding:6px 8px 14px;display:flex}.brand-logo{background:var(--text);flex-shrink:0;width:26px;height:26px;-webkit-mask:url(/logo.png) 50%/contain no-repeat;mask:url(/logo.png) 50%/contain no-repeat}.brand .name{font-weight:var(--weight-semibold);font-size:var(--text-subtitle);letter-spacing:0;line-height:26px}.brand .ver{font-family:var(--font-code);font-size:var(--text-micro);color:var(--muted);line-height:var(--leading-tight);background:var(--raised);border:1px solid var(--border);border-radius:var(--radius-pill);align-self:center;padding:2px 6px}.sidebar nav{flex-direction:column;gap:4px;display:flex}.nav-item{border-radius:var(--radius-sm);text-align:left;cursor:pointer;width:100%;color:var(--muted);font:inherit;font-size:var(--text-control);font-weight:var(--weight-medium);transition:background var(--motion-fast), color var(--motion-fast);background:0 0;border:none;align-items:center;gap:10px;padding:8px 10px;display:flex}.nav-item:hover,.nav-item.active{background:var(--accent-soft);color:var(--text)}.nav-item.active{font-weight:var(--weight-semibold)}.nav-item svg{width:17px;height:17px;color:var(--faint);flex-shrink:0}.nav-item.active svg{color:var(--text)}.sidebar-foot{flex-direction:column;gap:2px;margin-top:auto;padding-top:12px;display:flex}.drawer-head{align-items:flex-start;display:flex}.drawer-head .brand{flex:auto;min-width:0}.mobile-topbar{display:none}.menu-toggle{border-radius:var(--radius-sm);min-width:44px;min-height:44px;color:var(--muted);cursor:pointer;transition:background var(--motion-fast), color var(--motion-fast);background:0 0;border:none;justify-content:center;align-items:center;padding:8px;display:none}.menu-toggle:hover{background:var(--accent-soft);color:var(--text)}.menu-toggle svg{width:20px;height:20px}.drawer-scrim{z-index:var(--z-overlay);background:var(--lightningcss-light,#14141452)var(--lightningcss-dark,#00000085);display:none;position:fixed;inset:0}.sidebar-link{color:var(--muted);font-size:var(--text-control);border-radius:var(--radius-sm);align-items:center;gap:9px;padding:8px 10px;text-decoration:none;display:flex}.sidebar-link:hover{background:var(--accent-soft);color:var(--text);text-decoration:none}.sidebar-link svg{width:16px;height:16px}.lang-toggle{width:100%;color:var(--muted);font-size:var(--text-control);border-radius:var(--radius-sm);transition:background var(--motion-fast), color var(--motion-fast);align-items:center;gap:9px;padding:8px 10px;display:flex;position:relative}.lang-toggle:hover{background:var(--accent-soft);color:var(--text)}.lang-toggle svg{flex-shrink:0;width:16px;height:16px}.lang-toggle .custom-select{width:100%;position:static!important}.lang-toggle .select-trigger{width:100%;color:inherit;font-size:var(--text-control);min-height:auto;box-shadow:none;-webkit-backdrop-filter:none;background:0 0;border:none;justify-content:space-between;padding:0}.lang-toggle .select-trigger:hover:not(:disabled){color:inherit;box-shadow:none;background:0 0;border:none}.lang-toggle .select-dropdown{background:var(--glass-rail);-webkit-backdrop-filter:var(--glass-blur);border:1px solid var(--border);box-shadow:var(--shadow-sm)}.lang-toggle .select-dropdown-beside{min-width:10rem;top:0;left:calc(100% + 6px);right:auto}.theme-toggle{text-align:left;cursor:pointer;width:100%;color:var(--muted);font:inherit;font-size:var(--text-control);border-radius:var(--radius-sm);transition:background var(--motion-fast), color var(--motion-fast);background:0 0;border:none;align-items:center;gap:9px;padding:8px 10px;display:flex}.theme-toggle:hover{background:var(--accent-soft);color:var(--text)}.theme-toggle svg{flex-shrink:0;width:16px;height:16px}.theme-toggle .mode{text-transform:capitalize}.stop-toggle{color:var(--red)}.stop-toggle:hover{background:var(--red-soft);color:var(--red)}.stop-toggle:disabled{opacity:.5;cursor:default}.main{min-width:0}.main-inner{max-width:980px;margin:0 auto;padding:32px 36px 64px}.main-inner.main-inner--combos{flex-direction:column;max-width:none;height:100dvh;min-height:100dvh;margin:0;padding:0;display:flex;overflow:hidden}.main-inner.main-inner--combos>.combos-workspace-shell{flex-direction:column;flex:auto;height:100%;min-height:0;display:flex}.page-head{justify-content:space-between;align-items:center;gap:16px;margin-bottom:6px;display:flex}.page-head h2{font-size:var(--text-title)}.page-sub{color:var(--muted);font-size:var(--text-body);max-width:70ch;margin:4px 0 22px}.page-tabs{border-bottom:1px solid var(--border);gap:2px;margin:2px 0 14px;display:flex}.page-tab{appearance:none;color:var(--muted);cursor:pointer;font:inherit;font-size:var(--text-control);background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:8px 12px}.page-tab:hover{color:var(--text)}.page-tab--active{color:var(--text);border-bottom-color:var(--accent);font-weight:var(--weight-semibold)}.page-tab:focus-visible{outline:2px solid var(--accent-ring);outline-offset:-2px}.page-sub b{color:var(--text);font-weight:var(--weight-semibold)}.api-page h2 svg{vertical-align:-.16em;width:1em;height:1em}.api-page .page-sub code{font-size:var(--text-label);color:var(--text);background:var(--raised);border:1px solid var(--border-soft);border-radius:var(--radius-xs);padding:1px 4px}.btn{border-radius:var(--radius-pill);font:inherit;font-size:var(--text-control);font-weight:var(--weight-medium);line-height:var(--leading-ui);cursor:pointer;transition:background var(--motion-fast), border-color var(--motion-fast), opacity var(--motion-fast);white-space:nowrap;border:1px solid #0000;justify-content:center;align-items:center;gap:7px;padding:8px 16px;display:inline-flex}.btn svg{width:15px;height:15px}.btn:disabled{opacity:.55;cursor:default}.btn-primary{background:var(--accent);color:var(--accent-ink)}.btn-primary:hover:not(:disabled){background:var(--accent-hover)}.btn-ghost{background:var(--bg);color:var(--text);border-color:var(--border)}.btn-ghost:hover:not(:disabled){background:var(--raised)}.btn-danger{color:var(--red);background:0 0;border-color:#f871714d}.btn-danger:hover:not(:disabled){background:var(--red-soft)}.btn-sm{font-size:var(--text-label);border-radius:var(--radius-pill);padding:4px 12px}.btn-icon{appearance:none;font:inherit;cursor:pointer;width:28px;height:28px;color:var(--muted);border-radius:var(--radius-sm);transition:background var(--motion-fast), color var(--motion-fast);background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.btn-icon:hover{background:var(--raised-hover);color:var(--text)}.btn-icon:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}.btn-icon svg{width:16px;height:16px;display:block}.btn.btn-ghost.btn-icon{width:28px;height:28px;padding:0}.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);min-width:0}.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:18px}.panel-accent{border-color:color-mix(in srgb, var(--accent) 28%, var(--border));background:color-mix(in srgb, var(--accent) 5%, var(--surface))}.api-panel{flex-direction:column;gap:10px;display:flex;overflow:hidden}.api-panel .panel-title,.api-panel .muted{margin:0}.api-form-row{align-items:center;gap:8px;min-width:0;display:flex}.api-form-row .input{flex:1;min-width:0}.api-code{min-width:0;color:var(--text);background:var(--raised);border:1px solid var(--border-soft);border-radius:var(--radius-sm);font-family:var(--font-code);font-size:var(--text-label);line-height:var(--leading-relaxed);white-space:pre;margin:0;padding:9px 11px;display:block;overflow-x:auto}.api-code-inline{white-space:nowrap}.api-actions{justify-content:flex-end;align-items:center;gap:4px;display:flex}.maintenance-head{flex-wrap:wrap;align-items:flex-start}.maintenance-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.maintenance-notice{align-items:flex-start;margin:14px 0 0}.update-row{justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px;display:flex}.update-row .field-label{margin:0}.update-empty{margin-bottom:14px;padding:18px}.update-box{flex-direction:column;gap:12px;display:flex}.update-command{font-size:var(--text-label);flex-wrap:wrap;align-items:flex-start;gap:6px;display:flex}.update-command .chip{white-space:pre-wrap;word-break:break-all;overflow-wrap:anywhere;flex:auto;min-width:0;max-width:100%;line-height:1.5}.update-recheck{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.update-recheck .btn{flex:none}.update-recheck-reason{min-width:0;font-size:var(--text-label);color:var(--muted);flex:200px}.update-restart{border-top:1px solid var(--border-soft);padding-top:12px}.injection-head{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.injection-label{font-weight:var(--weight-semibold)}@media (width<=800px){.injection-head{gap:8px}.injection-label{flex:1 0 calc(100% - 70px);order:1}.injection-head>.badge{order:1;margin-left:auto}.injection-head>.custom-select{order:2}}.stat-row{grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:28px;display:grid}.stat-row>.stat{flex-direction:column;justify-content:center;min-height:80px;display:flex}@media (width<=1100px){.stat-row{grid-template-columns:repeat(3,1fr)}}@media (width<=640px){.stat-row{grid-template-columns:repeat(2,1fr)}}.stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);transition:border-color var(--motion-fast);padding:14px 16px}.stat:hover{border-color:var(--faint)}.stat .label{font-size:var(--text-label);color:var(--muted);font-weight:var(--weight-medium);align-items:center;gap:6px;margin-bottom:6px;display:flex}.stat .label svg{width:14px;height:14px}.stat .value{font-size:var(--text-title);font-weight:var(--weight-semibold);letter-spacing:0;line-height:var(--leading-tight)}.stat .value.mono{font-family:var(--font-code);font-size:var(--text-subtitle)}.model-group-head{font-size:var(--text-control);font-weight:var(--weight-semibold);color:var(--text);align-items:baseline;gap:8px;margin:0 0 8px;display:flex}.model-group-head .count{font-family:var(--font-code);font-weight:var(--weight-medium);color:var(--faint);font-size:var(--text-label)}.group-head{cursor:pointer;background:var(--surface);transition:background var(--motion-fast);padding:10px 12px}.group-head:hover{background:var(--hover)}.group-head.open{border-bottom:1px solid var(--border-soft)}.models-combos-card{overflow:hidden}.models-combo-row{min-height:var(--control-lg);padding:0 var(--space-3) 0 calc(var(--space-8) + var(--space-0-5));gap:var(--space-2);align-items:center}.model-grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;display:grid}.model-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);transition:border-color var(--motion-fast), background var(--motion-fast);padding:10px 12px}.model-card:hover{border-color:var(--faint);background:var(--hover)}.model-card .id{font-family:var(--font-code);font-weight:var(--weight-semibold);font-size:var(--text-control);letter-spacing:0;color:var(--text)}.badge{font-size:var(--text-caption);font-weight:var(--weight-semibold);line-height:var(--leading-ui);border-radius:var(--radius-pill);font-family:var(--font-code);letter-spacing:0;border:1px solid #0000;align-items:center;gap:5px;padding:2px 8px;display:inline-flex}.badge-accent{background:var(--accent-soft);color:var(--text)}.badge-green{background:var(--green-soft);color:var(--green)}.badge-amber{background:var(--amber-soft);color:var(--amber)}.badge-muted{background:var(--raised);color:var(--muted);border:1px solid var(--border)}.badge-clickable{cursor:pointer;transition:filter var(--motion-fast);appearance:none}.badge-clickable:hover{filter:brightness(1.1)}.badge-disabled{opacity:.5;cursor:default}.card-badges{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;display:inline-flex}.card-badges .badge{flex-shrink:0}.confirm-icon{border-radius:var(--radius-round);background:var(--amber-soft);width:44px;height:44px;color:var(--amber);justify-content:center;align-items:center;margin:0 auto 12px;display:flex}.credit-list{flex-direction:column;gap:6px;display:flex}.credit-item{border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--raised);transition:border-color var(--motion-fast);padding:8px 10px}.credit-next{border-color:var(--amber);background:var(--amber-soft)}.credit-item-head{color:var(--text);font-size:var(--text-label);font-weight:var(--weight-semibold);align-items:center;gap:6px;margin-bottom:3px;display:flex}.credit-item-head svg{color:var(--amber);flex-shrink:0}.credit-item-dates{font-size:var(--text-caption);font-family:var(--font-code);color:var(--muted);justify-content:space-between;display:flex}.credit-urgent{color:var(--red);font-weight:var(--weight-semibold)}.dot{border-radius:var(--radius-round);flex-shrink:0;width:7px;height:7px}.dot-green{background:var(--green);box-shadow:0 0 0 3px var(--green-soft)}.dot-red{background:var(--red);box-shadow:0 0 0 3px var(--red-soft)}.tbl{border-collapse:collapse;width:100%;font-size:var(--text-control)}.tbl thead th{text-align:left;color:var(--muted);font-weight:var(--weight-medium);font-size:var(--text-label);border-bottom:1px solid var(--border);padding:9px 12px}.tbl tbody td{border-bottom:1px solid var(--border-soft);padding:10px 12px}.tbl tbody tr:last-child td{border-bottom:none}.tbl tbody tr:hover td{background:var(--hover)}.tbl .num{text-align:right;font-family:var(--font-code);font-variant-numeric:tabular-nums}.tbl-wrap{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);overflow-x:auto}.input,textarea.input{border-radius:var(--radius-sm);background:var(--raised);border:1px solid var(--border);width:100%;color:var(--text);font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);transition:border-color var(--motion-fast);padding:8px 11px}.input::placeholder{color:var(--faint)}.input:focus{border-color:var(--faint);box-shadow:0 0 0 3px var(--accent-soft);outline:none}textarea.input{resize:vertical;font-family:var(--font-code);line-height:var(--leading-relaxed)}.field-label{font-size:var(--text-label);color:var(--muted);font-weight:var(--weight-medium);margin-bottom:5px;display:block}select.input{appearance:none}.select-sm{border-radius:var(--radius-pill);background:color-mix(in oklab, canvas 75%, transparent);-webkit-backdrop-filter:blur(12px)saturate(1.3);border:1px solid var(--border);color:var(--text);font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);cursor:pointer;transition:border-color var(--motion-fast), box-shadow var(--motion-fast);padding:6px 12px;box-shadow:0 2px 8px #0000000f}.select-sm:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);outline:none}.select-sm:hover:not(:disabled){border-color:var(--faint);box-shadow:0 2px 12px #0000001a}.select-sm:disabled{opacity:.5;cursor:default;-webkit-backdrop-filter:none}.select-trigger{border-radius:var(--radius-pill);background:color-mix(in oklab, canvas 75%, transparent);-webkit-backdrop-filter:blur(12px)saturate(1.3);border:1px solid var(--border);color:var(--text);font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);cursor:pointer;transition:border-color var(--motion-fast), box-shadow var(--motion-fast);white-space:nowrap;align-items:center;gap:6px;padding:6px 12px;display:inline-flex;box-shadow:0 2px 8px #0000000f}.select-trigger:hover:not(:disabled){border-color:var(--faint);box-shadow:0 2px 12px #0000001a}.select-trigger:disabled{opacity:.5;cursor:default}.select-dropdown{z-index:var(--z-popover);background:color-mix(in oklab, canvas 84%, transparent);-webkit-backdrop-filter:blur(20px)saturate(1.4);border:1px solid var(--border);border-radius:var(--radius);min-width:100%;max-height:280px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;overflow-y:auto;box-shadow:0 8px 32px #00000029}.select-dropdown-right{right:0;left:auto!important}.select-dropdown-beside{min-width:10rem;top:0;left:calc(100% + 6px);right:auto}.select-option{text-align:left;border-radius:var(--radius-sm);width:100%;color:var(--text);font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);cursor:pointer;transition:background var(--motion-fast);white-space:nowrap;background:0 0;border:none;padding:7px 12px;display:block}.select-option:hover{background:var(--hover)}.select-option.active{background:var(--accent-soft);color:var(--accent);font-weight:var(--weight-semibold)}.switch{border-radius:var(--radius-pill);border:1px solid var(--border);cursor:pointer;background:var(--raised);vertical-align:middle;width:34px;height:20px;transition:background var(--motion-normal), border-color var(--motion-normal);appearance:none;flex-shrink:0;align-items:center;padding:2px;line-height:0;display:inline-flex}.switch.on{background:var(--toggle-on-bg);border-color:var(--toggle-on-bg)}.switch:disabled{opacity:.6;cursor:default}.switch .knob{border-radius:var(--radius-round);width:14px;height:14px;transition:transform var(--motion-normal), background var(--motion-normal);background:var(--lightningcss-light,#fff)var(--lightningcss-dark,#ececec);transform:translate(0);box-shadow:0 0 0 1px #10182814,0 1px 1px #1018282e}.switch.on .knob{background:var(--toggle-dot-color);transform:translate(14px);box-shadow:0 0 0 1px #0000001f}.muted{color:var(--muted)}.faint{color:var(--faint)}.row{align-items:center;gap:10px;display:flex}.spread{justify-content:space-between;align-items:center;gap:12px;display:flex}.setting-hint{font-size:var(--text-control);line-height:var(--leading-body);margin-top:3px}.stack{flex-direction:column;display:flex}.chip{font-family:var(--font-code);font-size:var(--text-label);line-height:var(--leading-ui);background:var(--raised);border:1px solid var(--border);border-radius:var(--radius-xs);color:var(--text);padding:1px 7px}.empty{text-align:center;border:1px dashed var(--border);border-radius:var(--radius);color:var(--muted);padding:56px 20px}.empty svg{width:30px;height:30px;color:var(--faint);margin-bottom:12px}.empty .title{color:var(--text);font-weight:var(--weight-semibold);margin-bottom:6px}.notice{font-size:var(--text-control);line-height:var(--leading-body);border-radius:var(--radius-sm);align-items:center;gap:8px;margin-bottom:14px;padding:9px 12px;display:flex}.notice svg{flex-shrink:0;width:15px;height:15px}.notice-ok{background:var(--green-soft);color:var(--green)}.notice-err{background:var(--red-soft);color:var(--red)}.h-section{font-size:var(--text-control);font-weight:var(--weight-semibold);line-height:var(--leading-ui);color:var(--text);align-items:center;gap:8px;margin:30px 0 12px;display:flex}.h-section .count{color:var(--muted);font-weight:var(--weight-medium);font-family:var(--font-code);font-size:var(--text-label)}.spin{border:2px solid var(--border);border-top-color:var(--accent);border-radius:var(--radius-round);width:14px;height:14px;animation:.7s linear infinite spin;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.sidebar,.lang-toggle .select-dropdown{background:var(--rail)}.modal-card{background:var(--surface)}}@media (prefers-reduced-transparency:reduce){body:before{display:none}.sidebar,.lang-toggle .select-dropdown{background:var(--rail);-webkit-backdrop-filter:none}.modal-card{background:var(--surface);-webkit-backdrop-filter:none}.modal-overlay{-webkit-backdrop-filter:none}}.modal-overlay{-webkit-backdrop-filter:blur(40px)saturate(1.2);z-index:var(--z-modal);background:var(--lightningcss-light,#11131cc7)var(--lightningcss-dark,#000000d1);justify-content:center;align-items:flex-start;padding:8vh 16px;display:flex;position:fixed;inset:0}dialog.modal-overlay{width:100%;max-width:none;height:100%;max-height:none;color:inherit;border:none;margin:0}dialog.modal-overlay::backdrop{background:0 0}.modal-card{background:color-mix(in oklab, canvas 92%, transparent);-webkit-backdrop-filter:blur(20px)saturate(1.4);border:1px solid var(--border);border-radius:var(--radius-lg);width:100%;max-width:520px;max-height:84vh;padding:20px;overflow-y:auto;box-shadow:0 8px 32px #0000002e}.modal-head{justify-content:space-between;align-items:center;margin-bottom:16px;display:flex}.modal-head h3{font-size:var(--text-subtitle)}.card-head{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:14px 16px 6px;display:flex}.card-head strong{overflow-wrap:anywhere;min-width:0}.card-sub{font-size:var(--text-label);line-height:var(--leading-body);color:var(--muted);overflow-wrap:anywhere;min-width:0;padding:0 16px 10px}.card-active{border-color:var(--accent-ring)}.card-right{font-size:var(--text-caption);color:var(--faint);align-items:center;gap:4px;margin-left:auto;display:flex}.btn-icon-danger.card-right{appearance:none;color:var(--red);cursor:pointer;background:0 0;border:1px solid #0000;justify-content:center}.btn-icon-danger.card-right:hover{background:var(--red-soft);border-color:var(--red-soft);color:var(--red)}.card-row{justify-content:space-between;align-items:center;padding:14px 16px;display:flex}.badge-primary{background:var(--accent-soft);color:var(--accent-hover)}.dot-blue{background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}.dot-muted{background:var(--muted)}.dot-amber{background:var(--amber);box-shadow:0 0 0 3px var(--amber-soft)}.section-sep{align-items:center;gap:10px;margin:20px 0 12px;display:flex}.section-label{font-size:var(--text-label);color:var(--muted);font-weight:var(--weight-medium);white-space:nowrap}.sep-line{background:var(--border);flex:1;height:1px}.quota-compact{gap:4px;padding:2px 16px 12px;display:grid}.quota-row{grid-template-columns:minmax(34px,max-content) 34px minmax(34px,44px) minmax(38px,42px) minmax(58px,1fr) minmax(30px,max-content);align-items:center;gap:8px;min-width:0;display:grid}.quota-label{font-size:var(--text-caption);color:var(--muted);font-weight:var(--weight-semibold)}.quota-val{font-size:var(--text-caption);font-family:var(--font-code);color:var(--text);text-align:right}.quota-reset-label{text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-caption);color:var(--faint);overflow:hidden}.quota-reset-day,.quota-reset-time{font-size:var(--text-caption);color:var(--muted);white-space:nowrap}.quota-reset-time{font-family:var(--font-code)}.bar{background:var(--raised);border-radius:var(--radius-2xs);min-width:0;height:5px;overflow:hidden}.bar-fill{border-radius:var(--radius-2xs);height:100%;transition:width var(--motion-normal)}.bar-green{background:var(--green)}.bar-amber{background:linear-gradient(90deg, var(--green), var(--amber))}.toggle{width:var(--toggle-w);height:var(--toggle-h);border-radius:var(--radius-pill);background:var(--toggle-off-bg);border:1px solid var(--border);cursor:pointer;transition:background var(--motion-normal), border-color var(--motion-normal);flex-shrink:0;position:relative}.toggle.on{background:var(--toggle-on-bg);border-color:var(--toggle-on-bg)}.toggle-knob{border-radius:var(--radius-round);width:16px;height:16px;transition:left var(--motion-normal), background var(--motion-normal);background:var(--lightningcss-light,#fff)var(--lightningcss-dark,#ececec);position:absolute;top:1px;left:1px}.toggle.on .toggle-knob{background:var(--toggle-dot-color);left:17px}.notice-warn{font-size:var(--text-label);line-height:var(--leading-body);border-radius:var(--radius-sm);background:var(--amber-soft);color:var(--amber);align-items:center;gap:6px;margin-bottom:12px;padding:8px 10px;display:flex}.notice-warn svg{flex-shrink:0;width:14px;height:14px}.modal-desc{font-size:var(--text-control);line-height:var(--leading-body);color:var(--muted);margin-bottom:14px}.modal-actions{gap:8px;margin-top:16px;display:flex}.modal-actions .btn{flex:1}.log-reqid{-webkit-line-clamp:2;word-break:break-all;-webkit-box-orient:vertical;max-width:14ch;display:-webkit-box;overflow:hidden}.log-col-model{overflow-wrap:break-word;word-break:normal;max-width:18ch}.log-col-tokens{min-width:10ch}table.logs-table{min-width:960px}.log-col-rate{white-space:nowrap;min-width:7ch}.log-col-cost{white-space:nowrap;min-width:10ch}.log-status-cell{min-width:7ch;line-height:var(--leading-tight);flex-direction:column;align-items:flex-start;gap:2px;display:inline-flex}.log-detail-btn{cursor:pointer;color:var(--accent-hover);font:inherit;font-size:var(--text-caption);white-space:nowrap;background:0 0;border:none;padding:0;text-decoration:underline}.log-detail-grid{font-size:var(--text-control);grid-template-columns:max-content minmax(0,1fr);gap:6px 14px;display:grid}.log-detail-break{word-break:break-all}.log-detail-card{max-width:760px}.log-detail-section{border-top:1px solid var(--border-soft);padding:14px 0}.log-detail-section:first-of-type{border-top:0;padding-top:0}.log-detail-section-title{font-size:var(--text-label);font-weight:var(--weight-semibold);color:var(--text);margin:0 0 10px}.log-detail-request-row{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}.log-detail-request-row>span{min-width:0}.log-detail-notes{color:var(--muted);font-size:var(--text-label);margin:10px 0 0;padding-left:18px}.log-detail-notes-line{font-size:var(--text-label);margin:8px 0 0}.log-detail-attempts-wrap{border:1px solid var(--border-soft);border-radius:var(--radius-sm);overflow-x:auto}.log-detail-attempts{min-width:680px}.log-detail-attempts th,.log-detail-attempts td{vertical-align:top}.log-detail-raw{margin-top:14px}.log-detail-raw>summary{cursor:pointer;color:var(--muted);font-size:var(--text-label)}.log-detail-raw[open]>summary{margin-bottom:6px}.usage-cost-row{border:1px solid var(--border-soft);border-radius:var(--radius-sm);background:var(--raised);align-items:baseline;gap:10px;margin:10px 0 4px;padding:10px 14px;display:flex}.usage-cost-value{font-size:var(--text-lg,1.15em)}@media (width<=760px){.modal-overlay{padding:16px 10px}.log-detail-card{max-height:calc(100dvh - 32px);padding:16px}.log-detail-grid{grid-template-columns:minmax(7rem,max-content) minmax(0,1fr);gap:8px 10px}.log-detail-request-row{flex-direction:column;align-items:flex-start}}.log-detail-json{background:var(--raised);border:1px solid var(--border-soft);border-radius:var(--radius-sm);font-family:var(--font-code);font-size:var(--text-caption);line-height:var(--leading-body);white-space:pre-wrap;word-break:break-all;max-height:40vh;margin:0;padding:10px 12px;overflow:auto}.setup-guide{font-size:var(--text-control);line-height:var(--leading-body);border:1px solid var(--border);border-radius:var(--radius-sm);margin-bottom:4px;padding:8px 12px}.setup-guide summary{cursor:pointer;color:var(--accent-hover);font-weight:var(--weight-medium)}.setup-guide summary:hover{text-decoration:underline}.setup-guide a{color:var(--accent-hover)}.list-row{text-align:left;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--raised);cursor:pointer;width:100%;color:var(--text);font:inherit;transition:background var(--motion-fast), border-color var(--motion-fast);justify-content:space-between;align-items:center;gap:10px;padding:11px 13px;display:flex}.list-row:hover{background:var(--raised-hover);border-color:var(--accent-ring)}.list-row .title{font-weight:var(--weight-semibold);font-size:var(--text-body)}.list-row .sub{font-size:var(--text-label);color:var(--muted);margin-top:2px}.prov-card{overflow:hidden}.prov-card-main{flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:12px;padding:15px 16px;display:flex}.prov-card-disabled{opacity:.62}.prov-card-info{flex:360px;align-items:flex-start;gap:11px;min-width:0;display:flex}.prov-card-copy{flex:1;min-width:0}.prov-title{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;margin-bottom:5px;display:flex}.provider-icon{border-radius:var(--radius-xs);background:var(--raised);border:1px solid var(--border-soft);width:31px;height:31px;color:var(--text);flex:none;justify-content:center;align-items:center;display:inline-flex}.provider-icon img{object-fit:contain;width:19px;height:19px;display:block}.prov-meta{flex-wrap:wrap;align-items:center;gap:5px;min-width:0;display:flex}.prov-meta>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%;overflow:hidden}.provider-quota{padding-left:58px}.provider-actions{flex-shrink:0;align-items:center;gap:8px;margin-left:auto;display:flex}.openai-mode-row{flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px;display:flex}.openai-mode-control .usage-segmented-btn{min-width:76px}.link-btn{color:var(--accent-hover);font:inherit;font-size:var(--text-control);cursor:pointer;background:0 0;border:none;padding:6px 2px;text-decoration:underline}.link-btn svg{flex-shrink:0;width:14px;height:14px}.prov-accounts-toggle{border:none;border-top:1px solid var(--border-soft);width:100%;color:var(--muted);font:inherit;font-size:var(--text-label);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:6px;min-height:24px;padding:4px 0;display:flex}.prov-accounts-toggle:hover{color:var(--text);background:var(--raised)}.prov-accounts-toggle .chev{transition:transform var(--motion-normal) ease;display:inline-flex}.prov-accounts-toggle .chev svg{width:12px;height:12px;transform:rotate(90deg)}.prov-accounts-toggle.open .chev svg{transform:rotate(-90deg)}.prov-accounts-list{border-top:1px solid var(--border-soft);flex-direction:column;gap:2px;padding:6px 16px 10px;display:flex}.prov-account-row{border-radius:var(--radius-xs);align-items:center;gap:8px;width:100%;min-height:32px;padding:6px 8px;display:flex}button.prov-account-row{text-align:left;color:var(--text);font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);cursor:pointer;background:0 0;border:none}button.prov-account-row:hover,.prov-account-row:hover{background:var(--raised)}button.prov-account-row.active{cursor:default}.prov-account-row-main{appearance:none;min-width:0;color:inherit;text-align:left;cursor:pointer;font:inherit;font-size:var(--text-control);line-height:var(--leading-ui);background:0 0;border:0;flex:auto;align-items:center;gap:8px;padding:0;display:flex}.prov-account-row-main:disabled{cursor:default;opacity:.72}.prov-account-row .prov-account-email{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}.prov-account-row .badge{flex:none}.prov-account-reauth{color:var(--accent);cursor:pointer;font:inherit;font-size:var(--text-label);border-radius:var(--radius-xs);background:0 0;border:none;flex:none;padding:4px 6px}.prov-account-reauth:hover:not(:disabled){color:var(--accent-hover);background:var(--raised)}.prov-account-reauth:disabled{opacity:.6;cursor:default}.prov-account-remove{color:var(--muted);cursor:pointer;border-radius:var(--radius-xs);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:4px;display:inline-flex}.prov-account-remove:hover{color:var(--red);background:var(--red-soft)}.prov-account-add{color:var(--muted);font-size:var(--text-label)}.prov-account-add:hover{color:var(--accent-hover)}.prov-account-keyform{cursor:default;gap:6px}.prov-account-keyform:hover{background:0 0}.prov-account-keyform .input-sm{min-width:0;font-size:var(--text-label);height:var(--control-sm);flex:auto;padding:4px 8px}.oauth-grid{grid-template-columns:minmax(140px,max-content) minmax(0,1fr) max-content;align-items:center;gap:10px 16px;display:grid}.oauth-row{grid-column:1/-1;grid-template-columns:subgrid;align-items:center;min-height:30px;display:grid}.oauth-name{font-size:var(--text-control);font-weight:var(--weight-semibold);align-items:center;gap:8px;min-width:0;display:inline-flex}.oauth-name-text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.provider-icon-sm{border-radius:var(--radius-xs);width:24px;height:24px}.provider-icon-sm img{width:15px;height:15px}.oauth-status{font-size:var(--text-control);align-items:center;gap:7px;min-width:0;display:inline-flex}.oauth-email{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.oauth-actions{justify-content:flex-end;align-items:center;gap:8px;min-width:0;display:inline-flex}.oauth-login-hint{font-size:var(--text-label);line-height:var(--leading-body);flex-direction:column;grid-column:1/-1;align-items:stretch;gap:8px;display:flex}.oauth-login-hint-links{flex-wrap:wrap;align-items:center;gap:8px;display:inline-flex}.oauth-device-code-wrap{border:1px solid var(--border);background:var(--surface);border-radius:10px;flex-wrap:wrap;align-items:center;gap:10px;padding:12px;display:flex}.oauth-device-code-label{font-size:var(--text-label);color:var(--text);font-weight:600}.oauth-device-code{letter-spacing:.14em;color:var(--text);-webkit-user-select:all;user-select:all;font-size:20px;font-weight:800}.oauth-login-paste{align-items:center;gap:8px;width:100%;display:flex}.oauth-login-paste .input{min-width:0;font-size:var(--text-label);flex:1;padding:6px 10px}@media (width<=760px){.app{grid-template-rows:auto 1fr;grid-template-columns:1fr}.mobile-topbar{z-index:var(--z-sticky);border-bottom:1px solid var(--border);background:var(--glass-rail);min-width:0;-webkit-backdrop-filter:var(--glass-blur);align-items:center;gap:2px;padding:4px 10px;display:flex;position:sticky;top:0}.mobile-topbar .brand{flex:auto;min-width:0;padding:4px}.mobile-topbar .stop-toggle{justify-content:center;width:auto;min-width:44px;min-height:44px;padding:8px}.menu-toggle{display:inline-flex}.sidebar{z-index:var(--z-popover);width:min(280px,84vw);height:100dvh;padding-bottom:calc(18px + env(safe-area-inset-bottom));visibility:hidden;transition:transform var(--motion-normal) ease, visibility var(--motion-normal);background:var(--lightningcss-light,#f9f9f9f7)var(--lightningcss-dark,#171717f5);outline:none;position:fixed;top:0;bottom:0;left:0;overflow-y:auto;transform:translate(-100%)}.sidebar.open{visibility:visible;transform:translate(0);box-shadow:0 12px 40px var(--lightningcss-light,#14141438)var(--lightningcss-dark,#00000080)}.drawer-scrim{display:block}.main-inner{padding:22px 18px 48px}.main-inner.main-inner--combos{height:100%;min-height:0;padding:0;overflow:hidden}.setting-row{flex-wrap:wrap}.setting-row .setting-copy{flex:100%!important}.setting-row .setting-controls{width:100%}.setting-row .setting-controls .select-sm{flex:1 1 0;min-width:0}.setting-row>.select-sm{width:100%}.api-form-row{flex-direction:column;align-items:stretch}.api-form-row .btn{width:100%;min-height:40px}.stat-row>.stat{min-width:100px}.tbl{min-width:460px}.usage-cards{grid-template-columns:repeat(2,minmax(0,1fr))!important}.provider-quota{padding-left:16px}.prov-meta{grid-template-columns:max-content minmax(0,1fr);width:100%;display:grid}.prov-meta .chip~span:not(:last-child){display:none}.oauth-grid{grid-template-columns:minmax(0,auto) minmax(0,1fr) max-content;column-gap:8px}.sidebar .lang-toggle .select-dropdown-beside{inset:auto auto calc(100% + 6px) 0}}.usage-cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:8px;display:grid}.usage-cards .stat-value{font-size:var(--text-title);font-weight:var(--weight-semibold);margin-top:4px}.usage-head{flex-wrap:wrap}.usage-filters{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.usage-segmented{border:1px solid var(--border);border-radius:var(--radius-pill);background:var(--surface);gap:2px;padding:2px;display:inline-flex}.usage-segmented-btn{color:var(--muted);border-radius:var(--radius-pill);cursor:pointer;font:inherit;white-space:nowrap;background:0 0;border:none;justify-content:center;align-items:center;gap:6px;padding:4px 12px;display:inline-flex}.usage-segmented-btn.active{background:var(--raised);color:var(--text);font-weight:var(--weight-semibold)}.usage-source-mark{width:var(--icon-sm);height:var(--icon-sm);object-fit:contain;flex:none}:root[data-theme=dark] .usage-source-mark{filter:invert()}@media (prefers-color-scheme:dark){:root:not([data-theme=light]) .usage-source-mark{filter:invert()}}@media (width<=760px){.usage-segmented-btn{min-height:var(--control-touch)}.openai-mode-row{flex-direction:column;align-items:stretch;gap:6px}.openai-mode-control{width:100%}.openai-mode-control .usage-segmented-btn{flex:1 1 0;min-width:0}}@media (width<=640px){.usage-source-btn .usage-source-label-collapsible{display:none}}@media (width<=360px){.usage-filters{flex-direction:column;align-items:stretch;width:100%}.usage-segmented{width:100%}.usage-segmented-btn{flex:1 1 0}}.panel-title{font-size:var(--text-body);font-weight:var(--weight-semibold);color:var(--text);margin:0 0 12px}.panel-head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:12px;display:flex}.panel-head .panel-title{margin:0}.panel-head .input{max-width:220px}.heatmap{--hm-cell:11px;--hm-gap:3px;flex-direction:column;gap:6px;padding-bottom:4px;display:flex;overflow-x:auto}.heatmap-months{font-size:var(--text-caption);color:var(--muted);width:max-content;margin-bottom:-2px;display:grid}.heatmap-day-spacer{grid-column:1}.heatmap-month{white-space:nowrap}.heatmap-body{gap:var(--hm-gap);width:max-content;display:flex}.heatmap-days{grid-template-rows:repeat(7, var(--hm-cell));row-gap:var(--hm-gap);font-size:var(--text-micro);color:var(--muted);background:var(--surface);z-index:1;flex-shrink:0;align-items:center;width:25px;display:grid;position:sticky;left:0}.heatmap-grid{gap:var(--hm-gap);display:grid}.heatmap-week{grid-template-rows:repeat(7, var(--hm-cell));gap:var(--hm-gap);display:grid}.heatmap-cell{width:var(--hm-cell);height:var(--hm-cell);border-radius:var(--radius-2xs);background:var(--border)}.heatmap-cell-0{background:var(--border)}.heatmap-cell-1{background:color-mix(in oklch, var(--green) 25%, var(--surface))}.heatmap-cell-2{background:color-mix(in oklch, var(--green) 50%, var(--surface))}.heatmap-cell-3{background:color-mix(in oklch, var(--green) 75%, var(--surface))}.heatmap-cell-4{background:var(--green)}.heatmap-legend{font-size:var(--text-label);align-self:flex-end;align-items:center;gap:4px;display:inline-flex;position:sticky;right:0}.heatmap-legend .heatmap-cell{width:10px;height:10px}.heatmap-tip{z-index:10;pointer-events:none;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);white-space:nowrap;font-size:var(--text-label);padding:6px 10px;position:fixed;transform:translate(-50%,-100%)translateY(-8px);box-shadow:0 6px 20px #00000059}.heatmap-tip-date{font-weight:var(--weight-semibold);color:var(--text);margin-bottom:2px}.heatmap-tip-val{color:var(--text);font-variant-numeric:tabular-nums}.heatmap-tip-req{font-size:var(--text-caption)}.usage-bar{background:var(--border);border-radius:var(--radius-pill);width:100%;min-width:60px;height:6px;overflow:hidden}.usage-bar-fill{background:var(--green);border-radius:var(--radius-pill);height:100%}.daybars{grid-template-columns:repeat(7,1fr);align-items:end;gap:10px;height:180px;padding-top:8px;display:grid}.daybar{flex-direction:column;justify-content:flex-end;align-items:center;gap:6px;height:100%;display:flex;position:relative}.daybar-track{background:var(--border);border-radius:var(--radius-xs);flex:1;align-items:flex-end;width:100%;max-width:48px;display:flex;overflow:hidden}.daybar-stack{border-radius:var(--radius-xs) var(--radius-xs) 0 0;width:100%;min-height:2px;transition:height var(--motion-normal) ease;flex-direction:column-reverse;display:flex;overflow:hidden}.daybar-seg{width:100%;min-height:1px}.daybar-count{font-size:var(--text-label);font-weight:var(--weight-semibold);color:var(--text)}.daybar-label{font-size:var(--text-caption);white-space:nowrap}.daybar:hover .daybar-track{outline:1px solid var(--border)}.daybar-tip{z-index:5;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);pointer-events:none;min-width:160px;padding:8px 10px;position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);box-shadow:0 6px 20px #00000059}.daybar-tip-date{font-size:var(--text-label);font-weight:var(--weight-semibold);color:var(--text);white-space:nowrap;margin-bottom:6px}.daybar-tip-row{font-size:var(--text-label);line-height:var(--leading-relaxed);align-items:center;gap:8px;display:flex}.daybar-tip-swatch{border-radius:var(--radius-2xs);flex-shrink:0;width:10px;height:10px}.daybar-tip-name{color:var(--text);white-space:nowrap;text-overflow:ellipsis;flex:1;max-width:160px;overflow:hidden}.daybar-tip-val{color:var(--muted);font-variant-numeric:tabular-nums}.usage-scroll{max-height:360px;overflow-y:auto}.usage-scroll thead th{z-index:1;background:var(--surface);position:sticky;top:0}.toggle{width:var(--toggle-w);height:var(--toggle-h);flex-shrink:0;display:inline-block;position:relative}.toggle input{opacity:0;width:0;height:0;position:absolute}.toggle .slider{background:var(--toggle-off-bg);border-radius:var(--radius-pill);cursor:pointer;transition:background var(--motion-normal) ease;position:absolute;inset:0}.toggle .slider:after{content:"";width:var(--toggle-dot);height:var(--toggle-dot);background:var(--toggle-dot-color);border-radius:var(--radius-round);transition:transform var(--motion-normal) ease;position:absolute;top:3px;left:3px}.toggle input:checked+.slider{background:var(--toggle-on-bg)}.toggle input:checked+.slider:after{transform:translateX(calc(var(--toggle-w) - var(--toggle-dot) - 6px))}.toggle input:focus-visible+.slider{outline:2px solid var(--accent-ring);outline-offset:2px}.toggle input:disabled+.slider{opacity:.5;cursor:not-allowed}.setting-row{justify-content:space-between;align-items:center;gap:16px;padding:12px 16px;display:flex}.setting-row+.setting-row{border-top:1px solid var(--border-soft)}.setting-label{flex-direction:column;gap:2px;min-width:0;display:flex}.setting-label .title{font-size:var(--text-body);font-weight:var(--weight-semibold);color:var(--text)}.setting-label .desc{font-size:var(--text-label);color:var(--muted);line-height:var(--leading-body)}.model-row-wrap{position:relative}.model-tip{z-index:10;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);pointer-events:none;min-width:320px;max-width:480px;max-height:360px;font-size:var(--text-control);line-height:var(--leading-relaxed);white-space:nowrap;padding:12px 16px;overflow-y:auto;box-shadow:0 6px 20px #00000059}.model-tip.has-actions{pointer-events:auto}.model-tip-id{font-family:var(--mono);font-size:var(--text-body);font-weight:var(--weight-semibold);color:var(--text);white-space:normal;word-break:break-all;margin-bottom:2px}.model-tip-display{color:var(--muted);margin-bottom:6px}.model-tip-grid{grid-template-columns:auto 1fr;gap:4px 16px;margin-bottom:6px;display:grid}.model-tip-key{color:var(--muted)}.model-tip-val{color:var(--text);font-family:var(--mono);font-size:var(--text-label)}.model-tip-actions{border-top:1px solid var(--border-soft);gap:6px;margin-top:8px;padding-top:8px;display:flex}
@@ -16,8 +16,8 @@
16
16
  } catch (e) {}
17
17
  })();
18
18
  </script>
19
- <script type="module" crossorigin src="/assets/index-d63HMU0x.js"></script>
20
- <link rel="stylesheet" crossorigin href="/assets/index-D6Fcl4yM.css">
19
+ <script type="module" crossorigin src="/assets/index-BkmJJgg6.js"></script>
20
+ <link rel="stylesheet" crossorigin href="/assets/index-Sg-7L_oZ.css">
21
21
  </head>
22
22
  <body>
23
23
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitkyc08/opencodex",
3
- "version": "2.7.33",
3
+ "version": "2.7.34",
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",
@@ -37,6 +37,9 @@ function toAnthropicContentPart(p: OcxContentPart): unknown {
37
37
  const DEFAULT_MAX_TOKENS = 8192;
38
38
  /** Safe ceiling for `max_tokens` (thinking + visible output) across current Claude 4.x models. */
39
39
  const REASONING_MAX_TOKENS_CEILING = 32_000;
40
+ /** Adaptive-thinking ceiling: max effort budget (32k) + OUTPUT_HEADROOM (8k).
41
+ * Must exceed REASONING_MAX_TOKENS_CEILING so effort=max actually preserves visible-output room. */
42
+ const ADAPTIVE_THINKING_CEILING = 40_192;
40
43
  /** Anthropic's documented minimum `thinking.budget_tokens`. */
41
44
  const MIN_THINKING_BUDGET = 1024;
42
45
  /** Visible-output room added above the thinking budget when sizing `max_tokens`. */
@@ -634,11 +637,14 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
634
637
  // default 8192-token request can spend everything on thought and return empty text.
635
638
  body.thinking = { type: "adaptive" };
636
639
  body.output_config = { effort: adaptiveEffort(parsed.options.reasoning) };
637
- const maxOut = parsed.options.maxOutputTokens ?? DEFAULT_MAX_TOKENS;
638
- body.max_tokens = Math.min(
639
- REASONING_MAX_TOKENS_CEILING,
640
- Math.max(maxOut, reasoningBudget(adaptiveEffort(parsed.options.reasoning)) + OUTPUT_HEADROOM),
641
- );
640
+ const explicitMaxOut = parsed.options.maxOutputTokens;
641
+ const wantBudget = reasoningBudget(parsed.options.reasoning);
642
+ const floor = wantBudget + OUTPUT_HEADROOM;
643
+ // Preserve explicit caller limits as-is; for omitted limits use the adaptive ceiling
644
+ // so effort=max (budget=32k) still leaves OUTPUT_HEADROOM tokens for visible output.
645
+ body.max_tokens = explicitMaxOut !== undefined
646
+ ? explicitMaxOut
647
+ : Math.min(ADAPTIVE_THINKING_CEILING, Math.max(DEFAULT_MAX_TOKENS, floor));
642
648
  } else {
643
649
  // Anthropic requires max_tokens > thinking.budget_tokens (max_tokens caps thinking +
644
650
  // visible output) and budget_tokens >= 1024. Codex sends the SAME value for both, which
@@ -854,10 +860,11 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
854
860
  }
855
861
  }
856
862
  const usage = json.usage as Record<string, number> | undefined;
863
+ const stopReason = typeof json.stop_reason === "string" ? json.stop_reason : undefined;
857
864
  events.push({
858
865
  type: "done",
859
866
  usage: usageFromAnthropic(usage),
860
- ...(typeof json.stop_reason === "string" ? { stopReason: json.stop_reason } : {}),
867
+ ...(stopReason ? { stopReason } : {}),
861
868
  });
862
869
  return events;
863
870
  },
@@ -80,13 +80,48 @@ export function isCursorModelAvailableForAccount(modelId: string, liveIds: reado
80
80
  /** Codex-facing id for Cursor's auto-router. Always kept in the catalog even when live discovery omits it. */
81
81
  export const CURSOR_AUTO_MODEL_ID = "auto";
82
82
 
83
+ /** Cursor Router's public optimization modes (cost -> intelligence Pareto frontier). */
84
+ export const CURSOR_ROUTING_LEVELS = ["cost", "balance", "intelligence"] as const;
85
+ export type CursorRoutingLevel = typeof CURSOR_ROUTING_LEVELS[number];
86
+
87
+ /**
88
+ * Codex cannot render Cursor's model-specific parameter control, so expose each optimization mode
89
+ * as a first-class routed model next to the backwards-compatible `cursor/auto` entry.
90
+ */
91
+ export const CURSOR_ROUTER_MODEL_IDS = [
92
+ CURSOR_AUTO_MODEL_ID,
93
+ ...CURSOR_ROUTING_LEVELS.map(level => `${CURSOR_AUTO_MODEL_ID}-${level}`),
94
+ ] as const;
95
+
83
96
  /** Wire id Cursor Connect expects for the auto-router (GetUsableModels returns `default`, not `auto`). */
84
97
  export const CURSOR_AUTO_WIRE_MODEL_ID = "default";
85
98
 
99
+ export interface CursorWireModelSelection {
100
+ modelId: string;
101
+ routingLevel?: CursorRoutingLevel;
102
+ }
103
+
104
+ /** Resolve a Codex-facing model id into Cursor's wire model plus optional router parameter. */
105
+ export function cursorWireModelSelection(modelId: string): CursorWireModelSelection {
106
+ const normalized = modelId.startsWith("cursor/") ? modelId.slice("cursor/".length) : modelId;
107
+ if (normalized === CURSOR_AUTO_MODEL_ID) return { modelId: CURSOR_AUTO_WIRE_MODEL_ID };
108
+ const prefix = `${CURSOR_AUTO_MODEL_ID}-`;
109
+ if (normalized.startsWith(prefix)) {
110
+ const level = normalized.slice(prefix.length);
111
+ if ((CURSOR_ROUTING_LEVELS as readonly string[]).includes(level)) {
112
+ return { modelId: CURSOR_AUTO_WIRE_MODEL_ID, routingLevel: level as CursorRoutingLevel };
113
+ }
114
+ }
115
+ return { modelId: normalized };
116
+ }
117
+
86
118
  /** Map a Codex-facing Cursor model id to the upstream wire id. */
87
119
  export function cursorCodexToWireModelId(modelId: string): string {
88
- const normalized = modelId.startsWith("cursor/") ? modelId.slice("cursor/".length) : modelId;
89
- return normalized === CURSOR_AUTO_MODEL_ID ? CURSOR_AUTO_WIRE_MODEL_ID : normalized;
120
+ return cursorWireModelSelection(modelId).modelId;
121
+ }
122
+
123
+ export function isCursorRouterModelId(modelId: string): boolean {
124
+ return (CURSOR_ROUTER_MODEL_IDS as readonly string[]).includes(modelId);
90
125
  }
91
126
 
92
127
  /** Filter the static Cursor seed to models this account can use. */
@@ -95,7 +130,7 @@ export function filterCursorConfiguredModelsByLiveDiscovery<T extends { id: stri
95
130
  liveIds: readonly string[],
96
131
  ): T[] {
97
132
  return configured.filter(model =>
98
- model.id === CURSOR_AUTO_MODEL_ID || isCursorModelAvailableForAccount(model.id, liveIds),
133
+ isCursorRouterModelId(model.id) || isCursorModelAvailableForAccount(model.id, liveIds),
99
134
  );
100
135
  }
101
136
 
@@ -108,7 +143,7 @@ export const CURSOR_STATIC_MODELS: readonly CursorModelInfo[] = normalizeCursorM
108
143
  // advertise effort so Codex exposes the tier picker. `supportsReasoningEffort` tracks whether the
109
144
  // model has *selectable effort tiers* (CURSOR_MODEL_EFFORT_TIERS), NOT merely whether it reasons:
110
145
  // gemini/grok/kimi/gpt-5-mini are reasoning models in the SOT but are sent bare (no tier picker).
111
- { id: "auto", contextWindow: CONTEXT_200K, supportsReasoningEffort: false },
146
+ ...CURSOR_ROUTER_MODEL_IDS.map(id => ({ id, contextWindow: CONTEXT_200K, supportsReasoningEffort: false })),
112
147
 
113
148
  { id: "claude-sonnet-5", contextWindow: CONTEXT_200K, supportsReasoningEffort: true },
114
149
  { id: "claude-4-sonnet", contextWindow: CONTEXT_200K },
@@ -8,23 +8,22 @@ export const CURSOR_SANDBOX_FULL_ACCESS_RE = /sandbox_mode[^\n]{0,80}danger-full
8
8
 
9
9
  /**
10
10
  * Config-owner-selected policy; explicit mode wins, legacy boolean maps to "on".
11
- * The UNSET default is "codex-sandbox": native local exec is APPROVED for requests that
12
- * declare the Codex danger-full-access sandbox (the normal full-access Codex flow — "approve
13
- * most") and DENIED for requests that do not. Set `nativeLocalExec: "off"` to deny all, or
14
- * "on" to always allow. Legacy `unsafeAllowNativeLocalExec: true` still maps to "on".
15
- * Security note: codex-sandbox trusts a caller-controlled full-access marker the proxy cannot
16
- * verify, and the auth-free loopback bind admits any local process — see the src/types.ts doc.
11
+ * The UNSET default is "off". `nativeLocalExec: "on"` is the only non-legacy setting that
12
+ * authorizes Cursor server-driven local read/write/delete/ls/grep/shell/fetch execution.
13
+ * `nativeLocalExec: "codex-sandbox"` is kept as a recognized legacy/deprecated spelling but is
14
+ * fail-closed: opencodex has no trustworthy per-request attestation that caller-supplied
15
+ * Responses instructions/system/developer prose reflects a real Codex sandbox state.
17
16
  */
18
17
  export function resolveCursorNativeExecMode(provider: OcxProviderConfig): CursorNativeExecMode {
19
18
  const mode = provider.nativeLocalExec;
20
19
  if (mode === "off" || mode === "codex-sandbox" || mode === "on") return mode;
21
- return provider.unsafeAllowNativeLocalExec === true ? "on" : "codex-sandbox";
20
+ return provider.unsafeAllowNativeLocalExec === true ? "on" : "off";
22
21
  }
23
22
 
24
23
  /**
25
24
  * True when the request itself declares the Codex full-access sandbox. Carriers are the
26
- * system/instructions entries and developer-role messages ONLY user/assistant/tool text
27
- * never authorizes (smallest spoof surface inside the codex-sandbox mode).
25
+ * system/instructions entries and developer-role messages ONLY. This is diagnostic/context
26
+ * metadata; request text is caller-controlled and never authorizes native local exec.
28
27
  */
29
28
  export function cursorRequestDeclaresFullAccess(
30
29
  request: { system: string[]; messages: Array<{ role: string; content: string }> },
@@ -38,12 +37,11 @@ export function cursorRequestDeclaresFullAccess(
38
37
  return false;
39
38
  }
40
39
 
41
- /** Effective per-request allowance: "on" always, "codex-sandbox" only when declared, "off" never. */
40
+ /** Effective per-request allowance: only server-local config opt-in enables native exec. */
42
41
  export function effectiveCursorNativeExecAllow(provider: OcxProviderConfig, requestDeclaresFullAccess: boolean): boolean {
43
42
  const mode = resolveCursorNativeExecMode(provider);
44
- if (mode === "on") return true;
45
- if (mode === "codex-sandbox") return requestDeclaresFullAccess;
46
- return false;
43
+ void requestDeclaresFullAccess;
44
+ return mode === "on";
47
45
  }
48
46
 
49
47
  export const CURSOR_EXEC_CASES_DENIED = [
@@ -3,7 +3,15 @@ import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
3
3
  import { namespacedToolName, type OcxProviderConfig, type OcxUsage } from "../../types";
4
4
  import { CONNECT_FLAG_END_STREAM, decodeAvailableConnectFrames, encodeConnectFrame } from "./framing";
5
5
  import { activePromptText, encodeCursorRunRequest } from "./protobuf-request";
6
- import { createCursorProtobufEventState, finalizeTurnEvents, mapCursorProtobufServerMessage, mapSyntheticMcpExecToToolEvents } from "./protobuf-events";
6
+ import {
7
+ createCursorContextUsageTracker,
8
+ createCursorProtobufEventState,
9
+ finalizeTurnEvents,
10
+ mapCursorProtobufServerMessage,
11
+ mapSyntheticMcpExecToToolEvents,
12
+ reportableContextTokens,
13
+ usageFromContextTokens,
14
+ } from "./protobuf-events";
7
15
  import {
8
16
  AgentClientMessageSchema,
9
17
  AgentServerMessageSchema,
@@ -60,6 +68,7 @@ const CLIENT_TOOL_FINALIZE_GRACE_MS = 50;
60
68
  const GENERIC_TOOL_COUNT_MIN_FINALIZE_GRACE_MS = 750;
61
69
  const GENERIC_TOOL_COUNT_MAX_FINALIZE_GRACE_MS = 1_800;
62
70
  const GENERIC_TOOL_COUNT_PER_TOOL_GRACE_MS = 125;
71
+ const cursorContextUsageTracker = createCursorContextUsageTracker();
63
72
 
64
73
  export class CursorMissingCredentialError extends Error {
65
74
  readonly code = "cursor_missing_credential";
@@ -452,6 +461,10 @@ class LiveCursorTransport implements CursorTransport {
452
461
  parallelToolCalls: request.parallelToolCalls,
453
462
  toolSchemas,
454
463
  cursorToolNameMap,
464
+ contextUsage: cursorContextUsageTracker.controlsForConversation(request.conversationId, {
465
+ clearPrior: request.contextUsageReset === true,
466
+ storeCheckpoints: request.contextUsageStoreCheckpoints !== false,
467
+ }),
455
468
  });
456
469
 
457
470
  this.open(request, signal, state, push, err => {
@@ -781,10 +794,15 @@ class LiveCursorTransport implements CursorTransport {
781
794
  */
782
795
  export function partialUsageFromEventState(state: ReturnType<typeof createCursorProtobufEventState>): OcxUsage | undefined {
783
796
  const out = state.usage.outputTokens;
784
- const ctx = state.contextTokens;
785
- if (ctx === undefined && out <= 0) return undefined;
797
+ const hasCurrentCheckpoint = Number.isFinite(state.contextTokens) && (state.contextTokens ?? 0) > 0;
798
+ const hasCurrentOutput = Number.isFinite(out) && out > 0;
799
+ // A carry-forward value belongs to an earlier successful turn. It can complete current-turn
800
+ // usage math after this turn emits output, but cannot by itself prove that a first-frame failure
801
+ // consumed anything.
802
+ if (!hasCurrentCheckpoint && !hasCurrentOutput) return undefined;
803
+ const ctx = reportableContextTokens(state);
786
804
  return ctx !== undefined
787
- ? { ...state.usage, inputTokens: Math.max(0, ctx - out), totalTokens: ctx, estimated: true }
805
+ ? { ...usageFromContextTokens(state, ctx), estimated: true }
788
806
  : { ...state.usage, estimated: true };
789
807
  }
790
808
 
@@ -5,6 +5,101 @@ import { normalizeArgKeys } from "./arg-normalize";
5
5
  import { OCX_RESPONSES_TOOL_PROVIDER, normalizeCursorWireName, responsesToolNameFromCursorWire } from "./tool-definitions";
6
6
  import type { CursorServerMessage } from "./types";
7
7
 
8
+ const DEFAULT_CONTEXT_USAGE_MAX_ENTRIES = 200;
9
+ const DEFAULT_CONTEXT_USAGE_TTL_MS = 60 * 60 * 1_000;
10
+
11
+ export interface CursorContextUsageControls {
12
+ /**
13
+ * Last observed absolute context size for the same Cursor conversation and uncompacted context
14
+ * epoch. Used only when the current turn produces output but no checkpoint.
15
+ */
16
+ carryForwardTokens?: number;
17
+ /** Persist a fresh checkpoint for later turns in this conversation. */
18
+ recordContextTokens?: (tokens: number) => void;
19
+ }
20
+
21
+ export interface CursorContextUsageTracker {
22
+ controlsForConversation(conversationId: string, options?: { clearPrior?: boolean; storeCheckpoints?: boolean }): CursorContextUsageControls;
23
+ get(conversationId: string): number | undefined;
24
+ record(conversationId: string, tokens: number): void;
25
+ clear(conversationId: string): void;
26
+ clearAll(): void;
27
+ }
28
+
29
+ interface CursorContextUsageEntry {
30
+ tokens: number;
31
+ updatedAt: number;
32
+ }
33
+
34
+ /**
35
+ * Bounded numeric-only carry-forward for Cursor context usage. Cursor checkpoints are absolute
36
+ * active-context sizes, but client-tool suspension can end a turn before a checkpoint arrives. Keep
37
+ * only the last known total per provider conversation so a no-checkpoint finalize does not overwrite
38
+ * a real active-context value with the current turn's tiny output delta. Context text, tool args,
39
+ * and model output are never stored here.
40
+ */
41
+ export function createCursorContextUsageTracker(options: { maxEntries?: number; ttlMs?: number; now?: () => number } = {}): CursorContextUsageTracker {
42
+ const maxEntries = options.maxEntries ?? DEFAULT_CONTEXT_USAGE_MAX_ENTRIES;
43
+ const ttlMs = options.ttlMs ?? DEFAULT_CONTEXT_USAGE_TTL_MS;
44
+ const now = options.now ?? (() => Date.now());
45
+ const entries = new Map<string, CursorContextUsageEntry>();
46
+
47
+ const prune = () => {
48
+ const at = now();
49
+ for (const [conversationId, entry] of entries) {
50
+ if (at - entry.updatedAt > ttlMs) entries.delete(conversationId);
51
+ }
52
+ while (entries.size > maxEntries) {
53
+ const oldest = entries.keys().next().value;
54
+ if (!oldest) break;
55
+ entries.delete(oldest);
56
+ }
57
+ };
58
+
59
+ const record = (conversationId: string, tokens: number) => {
60
+ if (!Number.isFinite(tokens) || tokens <= 0) return;
61
+ prune();
62
+ const existing = entries.get(conversationId);
63
+ if (existing && existing.tokens >= tokens) {
64
+ entries.delete(conversationId);
65
+ entries.set(conversationId, { tokens: existing.tokens, updatedAt: now() });
66
+ return;
67
+ }
68
+ entries.delete(conversationId);
69
+ entries.set(conversationId, { tokens, updatedAt: now() });
70
+ prune();
71
+ };
72
+
73
+ const get = (conversationId: string): number | undefined => {
74
+ prune();
75
+ const entry = entries.get(conversationId);
76
+ if (!entry) return undefined;
77
+ entries.delete(conversationId);
78
+ entries.set(conversationId, { tokens: entry.tokens, updatedAt: now() });
79
+ return entry.tokens;
80
+ };
81
+
82
+ return {
83
+ controlsForConversation(conversationId, requestOptions = {}) {
84
+ if (requestOptions.clearPrior === true) entries.delete(conversationId);
85
+ const storeCheckpoints = requestOptions.storeCheckpoints !== false;
86
+ const carryForwardTokens = storeCheckpoints ? get(conversationId) : undefined;
87
+ return {
88
+ ...(carryForwardTokens !== undefined ? { carryForwardTokens } : {}),
89
+ ...(storeCheckpoints ? { recordContextTokens: tokens => record(conversationId, tokens) } : {}),
90
+ };
91
+ },
92
+ get,
93
+ record,
94
+ clear(conversationId) {
95
+ entries.delete(conversationId);
96
+ },
97
+ clearAll() {
98
+ entries.clear();
99
+ },
100
+ };
101
+ }
102
+
8
103
  export interface CursorProtobufEventState {
9
104
  usage: OcxUsage;
10
105
  /**
@@ -16,6 +111,14 @@ export interface CursorProtobufEventState {
16
111
  * share one field, or Codex double-counts (e.g. 10000 then 10300 surfacing as 20300).
17
112
  */
18
113
  contextTokens?: number;
114
+ /**
115
+ * Session-level last-known absolute context size for this Cursor conversation. This is a fallback
116
+ * for no-checkpoint client-tool finalize turns only; any checkpoint observed during the current
117
+ * turn remains authoritative, with monotonic max semantics unless a compaction boundary reset the
118
+ * conversation cache before the turn.
119
+ */
120
+ contextCarryForwardTokens?: number;
121
+ recordContextTokens?: (tokens: number) => void;
19
122
  openToolCalls: Map<string, { name: string; args: string }>;
20
123
  completedToolCalls: Set<string>;
21
124
  /** Set once a terminal `done`/truncation has been emitted, so post-terminal frames stay inert. */
@@ -29,7 +132,13 @@ export interface CursorProtobufEventState {
29
132
  cursorToolNameMap?: Map<string, string>;
30
133
  }
31
134
 
32
- export function createCursorProtobufEventState(options: { clientToolNames?: Iterable<string>; parallelToolCalls?: boolean; toolSchemas?: Map<string, unknown>; cursorToolNameMap?: Map<string, string> } = {}): CursorProtobufEventState {
135
+ export function createCursorProtobufEventState(options: {
136
+ clientToolNames?: Iterable<string>;
137
+ parallelToolCalls?: boolean;
138
+ toolSchemas?: Map<string, unknown>;
139
+ cursorToolNameMap?: Map<string, string>;
140
+ contextUsage?: CursorContextUsageControls;
141
+ } = {}): CursorProtobufEventState {
33
142
  return {
34
143
  // Cursor provides no authoritative usage frame; token counts are heuristic estimates from
35
144
  // checkpoint/delta events, so mark estimated from the start.
@@ -41,6 +150,30 @@ export function createCursorProtobufEventState(options: { clientToolNames?: Iter
41
150
  startedClientToolCalls: 0,
42
151
  ...(options.toolSchemas ? { toolSchemas: options.toolSchemas } : {}),
43
152
  ...(options.cursorToolNameMap ? { cursorToolNameMap: options.cursorToolNameMap } : {}),
153
+ ...(options.contextUsage?.carryForwardTokens !== undefined ? { contextCarryForwardTokens: options.contextUsage.carryForwardTokens } : {}),
154
+ ...(options.contextUsage?.recordContextTokens ? { recordContextTokens: options.contextUsage.recordContextTokens } : {}),
155
+ };
156
+ }
157
+
158
+ function observeContextTokens(state: CursorProtobufEventState, usedTokens: number): void {
159
+ if (!Number.isFinite(usedTokens) || usedTokens <= 0) return;
160
+ if (usedTokens > (state.contextTokens ?? 0)) state.contextTokens = usedTokens;
161
+ state.recordContextTokens?.(usedTokens);
162
+ }
163
+
164
+ export function reportableContextTokens(state: CursorProtobufEventState): number | undefined {
165
+ const current = state.contextTokens;
166
+ const carry = state.contextCarryForwardTokens;
167
+ if (current === undefined) return carry;
168
+ if (carry === undefined) return current;
169
+ return Math.max(current, carry);
170
+ }
171
+
172
+ export function usageFromContextTokens(state: CursorProtobufEventState, contextTokens: number): OcxUsage {
173
+ return {
174
+ ...state.usage,
175
+ inputTokens: Math.max(0, contextTokens - state.usage.outputTokens),
176
+ totalTokens: contextTokens,
44
177
  };
45
178
  }
46
179
 
@@ -204,12 +337,14 @@ export function mapCursorProtobufServerMessage(
204
337
  serverMessage: AgentServerMessage,
205
338
  state: CursorProtobufEventState,
206
339
  ): CursorServerMessage[] {
340
+ if (state.terminated) return [];
341
+
207
342
  if (serverMessage.message.case === "conversationCheckpointUpdate") {
208
343
  const usedTokens = serverMessage.message.value.tokenDetails?.usedTokens ?? 0;
209
344
  // `usedTokens` is the ABSOLUTE conversation context size, not a per-turn output delta. Track it
210
345
  // separately (monotonic max) and surface it as `done.usage.totalTokens`; folding it into
211
346
  // `outputTokens` (which also accumulates `tokenDelta`) double-counts in Codex. See contextTokens.
212
- if (usedTokens > (state.contextTokens ?? 0)) state.contextTokens = usedTokens;
347
+ observeContextTokens(state, usedTokens);
213
348
  return [];
214
349
  }
215
350
 
@@ -298,12 +433,9 @@ export function finalizeTurnEvents(state: CursorProtobufEventState): CursorServe
298
433
  // render the additive pair instead of total_tokens, so leaving inputTokens at 0 makes a 16k-context
299
434
  // first turn display as "9 used". Keep outputTokens as the per-turn delta and clamp the inferred
300
435
  // input to 0 in case Cursor reports a checkpoint smaller than the streamed output delta.
301
- const usage: OcxUsage = state.contextTokens !== undefined
302
- ? {
303
- ...state.usage,
304
- inputTokens: Math.max(0, state.contextTokens - state.usage.outputTokens),
305
- totalTokens: state.contextTokens,
306
- }
436
+ const contextTokens = reportableContextTokens(state);
437
+ const usage: OcxUsage = contextTokens !== undefined
438
+ ? usageFromContextTokens(state, contextTokens)
307
439
  : { ...state.usage };
308
440
  return [{ type: "done", usage }];
309
441
  }