Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export default function App() {
{page === "storage" && <Storage apiBase={API_BASE} />}
{page === "codex-auth" && <CodexAuth apiBase={API_BASE} />}
{page === "api" && <ApiKeys apiBase={API_BASE} viewMode={viewMode} />}
{page === "claude" && <ClaudeCode apiBase={API_BASE} />}
{page === "claude" && <ClaudeCode apiBase={API_BASE} viewMode={viewMode} />}
</ErrorBoundary>
</div>
</main>
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ export const de = {
"claude.networkError": "Netzwerkfehler — läuft der Proxy?",
"claude.toggleAria": "Claude-Verbindung umschalten",
"claude.none": "Keine",
"claude.workspace.settings": "Einstellungen",
"common.close": "Schließen",
"common.ok": "OK",
"app.logoAria": "opencodex-Logo",
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ export const en = {
"claude.networkError": "Network error — is the proxy running?",
"claude.toggleAria": "Toggle Claude connection",
"claude.none": "None",
"claude.workspace.settings": "Settings",

// Combos workspace
"cws.loading": "Loading combos…",
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ export const ja: Record<TKey, string> = {
"claude.networkError": "ネットワークエラー — プロキシは起動していますか?",
"claude.toggleAria": "Claude 接続を切り替え",
"claude.none": "なし",
"claude.workspace.settings": "設定",

// Combos workspace
"cws.loading": "コンボを読み込み中…",
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ export const ko: Record<TKey, string> = {
"claude.networkError": "네트워크 오류 — 프록시가 실행 중인가요?",
"claude.toggleAria": "Claude 인바운드 켜기/끄기",
"claude.none": "없음",
"claude.workspace.settings": "설정",
"common.close": "닫기",
"common.ok": "확인",
"app.logoAria": "opencodex 로고",
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ export const ru: Record<TKey, string> = {
"claude.networkError": "Ошибка сети — запущен ли прокси?",
"claude.toggleAria": "Переключить подключение Claude",
"claude.none": "Нет",
"claude.workspace.settings": "Настройки",

// Combos workspace
"cws.loading": "Загрузка комбо…",
Expand Down
1 change: 1 addition & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ export const zh: Record<TKey, string> = {
"claude.networkError": "网络错误 — 代理是否在运行?",
"claude.toggleAria": "切换 Claude 连接",
"claude.none": "无",
"claude.workspace.settings": "设置",
"common.close": "关闭",
"common.ok": "确定",
"app.logoAria": "opencodex 徽标",
Expand Down
333 changes: 199 additions & 134 deletions gui/src/pages/ClaudeCode.tsx

Large diffs are not rendered by default.

136 changes: 136 additions & 0 deletions gui/src/styles-claudecode-workspace.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/* ============================================================================
claudecode-workspace — isolated stylesheet (mirrors providers-workspace layout DNA)
Namespace: claudecode-workspace- | widgets: ccw-
Uses only design tokens from styles.css. No gradients.
============================================================================ */

.main-inner:has(.claudecode-workspace-shell) {
max-width: 1200px;
}

.claudecode-workspace-shell {
width: 100%;
min-width: 0;
}

.claudecode-workspace-root {
display: grid;
grid-template-columns: minmax(240px, 280px) minmax(0, 1fr);
gap: var(--space-4);
width: 100%;
max-width: 100%;
min-height: 480px;
}

/* ── Rail ─────────────────────────────────────────────── */

.claudecode-workspace-rail {
display: flex;
flex-direction: column;
gap: var(--space-3);
border-right: 1px solid var(--border);
padding-right: var(--space-3);
min-width: 0;
}

.claudecode-workspace-rail-list {
display: flex;
flex-direction: column;
gap: 2px;
min-height: 0;
}

.claudecode-workspace-rail-row {
display: flex;
flex-direction: column;
gap: var(--space-0-5);
width: 100%;
min-height: 46px;
appearance: none;
background: none;
border: none;
border-radius: var(--radius-sm);
padding: var(--space-1-5) var(--space-2);
cursor: pointer;
text-align: left;
color: inherit;
font: inherit;
overflow: hidden;
}

.claudecode-workspace-rail-row:hover {
background: var(--surface-2);
}

.claudecode-workspace-rail-row--selected {
background: var(--surface-2);
box-shadow: inset 0 0 0 1px var(--border);
}

.claudecode-workspace-rail-name {
font-size: var(--text-body);
font-weight: var(--weight-medium);
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.claudecode-workspace-rail-meta {
font-size: var(--text-caption);
color: var(--faint);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* ── Main pane ────────────────────────────────────────── */

.claudecode-workspace-main {
display: flex;
flex-direction: column;
gap: var(--space-4);
min-width: 0;
}

.ccw-detail-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-3);
flex-wrap: wrap;
}

.ccw-detail-title {
font-size: var(--text-h2);
font-weight: var(--weight-semibold);
color: var(--text);
margin: 0;
}

.ccw-body {
display: flex;
flex-direction: column;
gap: var(--space-3);
min-width: 0;
}

/* Match Settings: section titles must not push content below the Settings card top. */
.ccw-body > .h-section {
margin-top: 0;
}

/* ── Responsive ───────────────────────────────────────── */

@media (max-width: 768px) {
.claudecode-workspace-root {
grid-template-columns: 1fr;
}

.claudecode-workspace-rail {
border-right: none;
border-bottom: 1px solid var(--border);
padding-right: 0;
padding-bottom: var(--space-3);
}
}
2 changes: 1 addition & 1 deletion gui/src/styles-combos-workspace.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@

.combos-workspace-rail-row.combos-workspace-rail-row--selected {
background: var(--accent-soft);
box-shadow: inset 3px 0 0 var(--accent);
box-shadow: inset 0 0 0 1px var(--border);
}

.combos-workspace-rail-row:focus-visible {
Expand Down
11 changes: 6 additions & 5 deletions gui/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@import "./styles-dashboard-workspace.css";
@import "./styles-usage-workspace.css";
@import "./styles-apikeys-workspace.css";
@import "./styles-claudecode-workspace.css";

:root {
/* default: follow the OS; [data-theme] below pins color-scheme so light-dark() obeys it */
Expand Down Expand Up @@ -670,11 +671,11 @@ select.input { appearance: none; }
/* Keyboard / aria-activedescendant focus — visible without relying on :hover. */
.select-option-active {
background: var(--hover);
box-shadow: inset 2px 0 0 var(--accent);
}
/* Selected + keyboard-highlighted: full inset ring (not a left stripe). */
.select-option.active.select-option-active {
background: var(--accent-soft);
box-shadow: inset 2px 0 0 var(--accent);
box-shadow: inset 0 0 0 1px var(--accent);
}

/* ---- switch ---- */
Expand Down Expand Up @@ -815,7 +816,7 @@ dialog.modal-overlay::backdrop {
.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; position: relative; transition: background var(--motion-normal), border-color var(--motion-normal); flex-shrink: 0; }
.toggle.on { background: var(--toggle-on-bg); border-color: var(--toggle-on-bg); }
.toggle-knob { width: 16px; height: 16px; background: light-dark(#ffffff, #ececec); border-radius: var(--radius-round); position: absolute; top: 1px; left: 1px; transition: left var(--motion-normal), background var(--motion-normal); }
.toggle-knob { width: 16px; height: 16px; background: light-dark(#ffffff, #ececec); border-radius: var(--radius-round); position: absolute; top: 50%; left: 1px; transform: translateY(-50%); transition: left var(--motion-normal), background var(--motion-normal); }
.toggle.on .toggle-knob { left: 17px; background: var(--toggle-dot-color); }
.toggle:disabled { cursor: not-allowed; opacity: 0.55; }
.codex-auto-switch-card { gap: 16px; flex-wrap: wrap; }
Expand Down Expand Up @@ -1167,9 +1168,9 @@ button.prov-account-row.active { cursor: default; }
.toggle { position: relative; display: inline-block; width: var(--toggle-w); height: var(--toggle-h); flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
.toggle .slider { position: absolute; inset: 0; background: var(--toggle-off-bg); border-radius: var(--radius-pill); cursor: pointer; transition: background var(--motion-normal) ease; }
.toggle .slider::after { content: ""; position: absolute; top: 3px; left: 3px; width: var(--toggle-dot); height: var(--toggle-dot); background: var(--toggle-dot-color); border-radius: var(--radius-round); transition: transform var(--motion-normal) ease; }
.toggle .slider::after { content: ""; position: absolute; top: 50%; left: 3px; width: var(--toggle-dot); height: var(--toggle-dot); background: var(--toggle-dot-color); border-radius: var(--radius-round); transform: translateY(-50%); transition: transform var(--motion-normal) ease; }
.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:checked + .slider::after { transform: translate(calc(var(--toggle-w) - var(--toggle-dot) - 6px), -50%); }
.toggle input:focus-visible + .slider { outline: 2px solid var(--accent-ring); outline-offset: 2px; }
.toggle input:disabled + .slider { opacity: 0.5; cursor: not-allowed; }

Expand Down
Loading