import { createTextNode as _$createTextNode } from "opentui:runtime-module:%40opentui%2Fsolid"; import { createComponent as _$createComponent } from "opentui:runtime-module:%40opentui%2Fsolid"; import { insertNode as _$insertNode } from "opentui:runtime-module:%40opentui%2Fsolid"; import { insert as _$insert } from "opentui:runtime-module:%40opentui%2Fsolid"; import { setProp as _$setProp } from "opentui:runtime-module:%40opentui%2Fsolid"; import { createElement as _$createElement } from "opentui:runtime-module:%40opentui%2Fsolid"; /** @jsxImportSource @opentui/solid */ export function buildKillswitchThresholdSeed(config, accountIds) { const readT = t => { const fh = t?.five_hour ?? t?.['5h'] ?? 5; const sd = t?.seven_day ?? t?.['1w'] ?? 10; const scoped = t?.scoped ?? 0; return { fh, sd, scoped }; }; const mainT = readT(config.main); const seedParts = [`main:${mainT.fh},${mainT.sd},${mainT.scoped}`]; for (const id of accountIds) { const t = readT(config.accounts?.[id] ?? config.main); seedParts.push(`${id}:${t.fh},${t.sd},${t.scoped}`); } return seedParts.join(' '); } export function buildAccountDialogOption(account) { const pct = account.quotaPercent != null ? ` ${Math.round(account.quotaPercent)}%` : ' \u2013%'; const status = !account.enabled ? ' (disabled)' : ''; return { title: `${account.label} [${account.role}]${status}${pct}`, value: account.id, ...(account.tierLabel && { description: account.tierLabel }) }; } function showText(api, text) { api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => (() => { var _el$ = _$createElement("box"), _el$2 = _$createElement("text"); _$insertNode(_el$, _el$2); _$setProp(_el$, "flexDirection", 'column'); _$setProp(_el$, "padding", 1); _$setProp(_el$, "width", '100%'); _$insert(_el$2, text); return _el$; })()); } export function openCommandDialog(api, payload, apply) { if (payload.command === 'claude-routing') { const current = payload.knobs.mode ?? 'main-first'; const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Claude routing", current: current, options: [{ title: 'Main first', value: 'main-first', description: 'Use the main account until exhausted' }, { title: 'Fallback first', value: 'fallback-first', description: 'Prefer fallback accounts, preserve main' }, { title: 'Sticky balanced', value: 'sticky-balanced', description: 'Balance new sessions by quota and keep each account sticky' }, { title: 'Reset this session', value: 'reset', description: 'Reassign this session on its next request' }], onSelect: option => { void apply('claude-routing', String(option.value)).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); } })); return; } if (payload.command === 'claude-fast' || payload.command === 'claude-dump') { const enabled = payload.knobs.enabled === true; const label = payload.command === 'claude-fast' ? 'fast mode' : 'request dump'; const DialogConfirm = api.ui.DialogConfirm; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogConfirm, { title: `Claude ${label}`, get message() { return `${payload.text}\n\n${enabled ? 'Disable' : 'Enable'} ${label}?`; }, onConfirm: () => { void apply(payload.command, enabled ? 'off' : 'on').then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); }, onCancel: () => api.ui.dialog.clear() })); return; } if (payload.command === 'claude-cache') { const enabled = payload.knobs.enabled === true; const mode = payload.knobs.mode ?? 'hybrid'; const currentValue = enabled ? mode : 'off'; const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Claude 1h cache", current: currentValue, options: [{ title: 'Off', value: 'off', description: 'Disable 1h cache' }, { title: 'Explicit', value: 'explicit', description: 'Existing OpenCode breakpoints' }, { title: 'Automatic', value: 'automatic', description: 'Top-level cache_control only' }, { title: 'Hybrid', value: 'hybrid', description: 'system + messages[0] + top-level' }], onSelect: option => { if (option.value === 'off') { void apply('claude-cache', 'off').then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); return; } void apply('claude-cache', `mode ${option.value}`).then(() => apply('claude-cache', 'on')).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); } })); return; } if (payload.command === 'claude-cachekeep') { const window = payload.knobs.window; const seed = window ? `${String(window.startHour).padStart(2, '0')}-${String(window.endHour).padStart(2, '0')}` : ''; const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "Claude cachekeep schedule", description: () => (() => { var _el$3 = _$createElement("text"); _$insert(_el$3, () => payload.text); return _el$3; })(), placeholder: "'always', HH-HH (e.g. 08-20), or 'off'", value: seed, onConfirm: value => { void apply('claude-cachekeep', value.trim()).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); }, onCancel: () => api.ui.dialog.clear() })); return; } if (payload.command === 'claude-killswitch') { const config = payload.knobs.config ?? {}; const accountIds = payload.knobs.accountIds ?? []; const enabled = config.enabled === true; const seed = buildKillswitchThresholdSeed(config, accountIds); const openEdit = () => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "Killswitch thresholds", description: () => (() => { var _el$4 = _$createElement("text"); _$insert(_el$4, () => payload.text); return _el$4; })(), placeholder: "main:5,10,0 work-alt:5,10,0", value: seed, onConfirm: value => { void apply('claude-killswitch', `set ${value.trim()}`).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); }, onCancel: () => api.ui.dialog.clear() })); }; const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Claude killswitch", options: [{ title: enabled ? 'Disable killswitch' : 'Enable killswitch', value: enabled ? 'off' : 'on', description: enabled ? 'Stop hard-blocking on low quota' : 'Hard-block requests when quota drops below thresholds' }, { title: 'Edit thresholds…', value: 'edit', description: 'Set per-account 5h,1w,scoped cutoffs' }], onSelect: option => { if (option.value === 'edit') { openEdit(); return; } void apply('claude-killswitch', String(option.value)).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); } })); return; } if (payload.command === 'claude-account') { const accounts = payload.knobs.accounts ?? []; const updateAccounts = r => { const updated = r.knobs.accounts; if (updated && updated.length > 0) { accounts.length = 0; accounts.push(...updated); } }; const buildL1 = () => { const DialogSelect = api.ui.DialogSelect; const l1Options = [{ title: 'Add account\u2026', value: '__add__', description: 'Add an API key or OAuth fallback account' }, ...accounts.map(buildAccountDialogOption)]; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Claude accounts", options: l1Options, onSelect: option => { if (option.value === '__add__') { openAddType(); return; } const account = accounts.find(a => a.id === option.value); if (!account) return; if (account.role === 'main') { const pct = account.quotaPercent != null ? ` ${Math.round(account.quotaPercent)}%` : ' \u2013%'; showText(api, `${account.label}\nRole: main (read-only)\nQuota:${pct}`); return; } openManage(account, false); } })); }; // -- Add type selection (OAuth vs API key) ------------------------------ const openAddType = () => { const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Add account", options: [{ title: 'OAuth (login)', value: 'oauth', description: 'Sign in to Claude via browser — works with Pro, Max, and Team plans' }, { title: 'API key', value: 'apikey', description: 'Provide an API key for an Anthropic-compatible endpoint' }, { title: 'Back', value: 'back' }], onSelect: option => { if (option.value === 'back') { buildL1(); return; } if (option.value === 'apikey') { openAddApiKey(); return; } openAddOAuthStart(); } })); }; // -- Add API key (multi-step: key → baseURL → authHeader → label) ------ const openAddApiKey = () => { const collected = {}; const openApiKeyPrompt = () => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "Add API key account \\u2014 API key", description: () => (() => { var _el$5 = _$createElement("text"); _$insertNode(_el$5, _$createTextNode(`Paste your API key (required).`)); return _el$5; })(), placeholder: "sk-ant-...", value: "", onConfirm: value => { const trimmed = value.trim(); if (!trimmed) { openAddType(); return; } collected.apiKey = trimmed; openBaseURLPrompt(); }, onCancel: () => openAddType() })); }; const openBaseURLPrompt = () => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "Add API key account \\u2014 base URL", description: () => (() => { var _el$7 = _$createElement("text"); _$insertNode(_el$7, _$createTextNode(`Anthropic-compatible API base URL. Default: https://api.kie.ai/claude`)); return _el$7; })(), placeholder: "https://api.kie.ai/claude", value: "", onConfirm: value => { const trimmed = value.trim(); collected.baseURL = trimmed || 'https://api.kie.ai/claude'; openAuthHeaderSelect(); }, onCancel: () => openApiKeyPrompt() })); }; const openAuthHeaderSelect = () => { const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Add API key account \\u2014 auth header", options: [{ title: 'Authorization: Bearer (default)', value: 'authorization-bearer', description: 'Standard bearer token authentication' }, { title: 'X-API-Key', value: 'x-api-key', description: 'Custom header-based API key' }], onSelect: option => { collected.authHeader = option.value; openLabelPrompt(); } })); }; const openLabelPrompt = () => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "Add API key account \\u2014 label", description: () => (() => { var _el$9 = _$createElement("text"); _$insertNode(_el$9, _$createTextNode(`A short name for this account (optional).`)); return _el$9; })(), placeholder: "e.g. Work API", value: "", onConfirm: value => { const trimmed = value.trim(); collected.label = trimmed || undefined; const apiKey = collected.apiKey; if (!apiKey) return; let args = `add-apikey ${apiKey}`; if (collected.baseURL && collected.baseURL !== 'https://api.kie.ai/claude') { args += ` --base-url ${collected.baseURL}`; } if (collected.authHeader && collected.authHeader !== 'authorization-bearer') { args += ` --auth-header ${collected.authHeader}`; } if (collected.label) { args += ` --label ${collected.label}`; } void apply('claude-account', args).then(r => { api.ui.toast({ message: r.text }); updateAccounts(r); buildL1(); }); }, onCancel: () => openAuthHeaderSelect() })); }; openApiKeyPrompt(); }; // -- Add OAuth (OSC-52 copy + code entry) ------------------------------ const openAddOAuthStart = () => { void apply('claude-account', 'add-oauth-start').then(r => { const oauthUrl = r.knobs.oauthUrl; updateAccounts(r); if (oauthUrl) { openOAuthUrlScreen(oauthUrl); } else { api.ui.toast({ message: r.text }); buildL1(); } }); }; const openOAuthUrlScreen = oauthUrl => { const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "OAuth sign-in", options: [{ title: 'Copy URL to clipboard', value: 'copy', description: oauthUrl }, { title: 'Enter sign-in code', value: 'code', description: 'Open the URL in your browser, sign in, then paste the callback URL or code' }, { title: 'Cancel', value: 'cancel' }], onSelect: option => { if (option.value === 'cancel') { buildL1(); return; } if (option.value === 'copy') { const ok = api.renderer.copyToClipboardOSC52(oauthUrl); if (ok) { api.ui.toast({ message: 'URL copied to clipboard' }); } else { api.ui.toast({ message: 'Copy unavailable \u2014 select the URL text above to copy' }); } openOAuthUrlScreen(oauthUrl); return; } openOAuthCodePrompt(oauthUrl); } })); }; const openOAuthCodePrompt = oauthUrl => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "OAuth sign-in \\u2014 enter code", description: () => (() => { var _el$1 = _$createElement("text"); _$insertNode(_el$1, _$createTextNode(`After signing in you will be redirected. Paste the full callback URL or authorization code below.`)); return _el$1; })(), placeholder: "Paste callback URL or code here", value: "", onConfirm: value => { const trimmed = value.trim(); if (!trimmed) { buildL1(); return; } openOAuthLabelPrompt(trimmed, oauthUrl); }, onCancel: () => openOAuthUrlScreen(oauthUrl) })); }; const openOAuthLabelPrompt = (code, oauthUrl) => { const DialogPrompt = api.ui.DialogPrompt; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogPrompt, { title: "OAuth sign-in \\u2014 label", description: () => (() => { var _el$11 = _$createElement("text"); _$insertNode(_el$11, _$createTextNode(`A short name for this account (optional).`)); return _el$11; })(), placeholder: "e.g. work", value: "", onConfirm: value => { const label = value.trim(); const args = label ? `add-oauth-finish ${code} --label ${label}` : `add-oauth-finish ${code}`; void apply('claude-account', args).then(r => { api.ui.toast({ message: r.text }); updateAccounts(r); buildL1(); }); }, onCancel: () => openOAuthCodePrompt(oauthUrl) })); }; // -- Manage existing account ------------------------------------------- const openManage = (account, isMain) => { const DialogSelect = api.ui.DialogSelect; const DialogConfirm = api.ui.DialogConfirm; api.ui.dialog.setSize('xlarge'); const options = []; if (!isMain) { const toggleLabel = account.enabled ? 'Disable' : 'Enable'; options.push({ title: toggleLabel, value: account.enabled ? 'disable' : 'enable', description: account.enabled ? 'Stop using this fallback account' : 'Allow this fallback account to be used' }); options.push({ title: 'Move up', value: 'move-up', description: 'Higher priority in fallback order' }); options.push({ title: 'Move down', value: 'move-down', description: 'Lower priority in fallback order' }); options.push({ title: 'Remove\u2026', value: 'remove', description: 'Delete this account permanently' }); } options.push({ title: 'Back', value: 'back' }); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { get title() { return `Manage ${account.label}`; }, options: options, onSelect: option => { if (option.value === 'back') { buildL1(); return; } if (option.value === 'remove') { api.ui.dialog.replace(() => _$createComponent(DialogConfirm, { get title() { return `Remove ${account.label}?`; }, get message() { return `Are you sure you want to remove the fallback account "${account.label}"?`; }, onConfirm: () => { void apply('claude-account', `remove ${account.id}`).then(r => { api.ui.toast({ message: r.text }); updateAccounts(r); buildL1(); }); }, onCancel: () => openManage(account, isMain) })); return; } void apply('claude-account', `${option.value} ${account.id}`).then(r => { api.ui.toast({ message: r.text }); updateAccounts(r); const updatedList = r.knobs.accounts; const refreshed = (updatedList && updatedList.length > 0 ? updatedList.find(a => a.id === account.id) : undefined) ?? account; openManage(refreshed, isMain); }); } })); }; buildL1(); return; } if (payload.command === 'claude-logging') { const current = payload.knobs.level ?? 'info'; const levels = ['error', 'warn', 'info', 'debug', 'trace']; const DialogSelect = api.ui.DialogSelect; api.ui.dialog.setSize('xlarge'); api.ui.dialog.replace(() => _$createComponent(DialogSelect, { title: "Claude log level", current: current, get options() { return levels.map(level => ({ title: level === current ? `\u2022 ${level}` : level, value: level })); }, onSelect: option => { void apply('claude-logging', String(option.value)).then(r => { api.ui.toast({ message: r.text }); api.ui.dialog.clear(); }); } })); return; } // fallback for quota (display-only) showText(api, payload.text); }