fix(terminal): resolve PTY shell exec error, simplify CLI, unify Config tabs, restore Studio CSS
All checks were successful
Beta Release / beta (push) Successful in 37s
Stable Release / stable (push) Successful in 37s

- Fix detectShell() to return full paths via LookPath (was returning bare
  names causing exec error on some systems)
- Add shell path validation before pty.Start to prevent crashes
- Simplify CLI: remove all subcommands, keep only desktop launch with --port
- Restore missing Studio shared CSS (code blocks, input area, animations)
- Replace Config vertical sidebar with horizontal nav-tabs matching main layout

💘 Generated with Crush

Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
Augustin
2026-04-21 23:06:39 +02:00
parent 7f674730c7
commit 0b221094f2
4 changed files with 63 additions and 570 deletions

View File

@@ -132,27 +132,23 @@ export default function Config({ api }) {
<div className="config-window">
{toast && <div className="config-toast">{toast}</div>}
<div className="config-sidebar">
<div className="config-tabs-bar">
{PANELS.map(p => {
const Icon = p.icon
return (
<div
key={p.id}
className={`config-sidebar-item ${activePanel === p.id ? 'active' : ''}`}
className={`nav-tab ${activePanel === p.id ? 'active' : ''}`}
onClick={() => setActivePanel(p.id)}
>
<Icon size={16} />
<span>{t(`config.panels.${p.id}`)}</span>
<span className="tab-icon"><Icon size={15} /></span>
{t(`config.panels.${p.id}`)}
</div>
)
})}
</div>
<div className="config-panel-area">
<div className="config-panel-header">
<h2 className="config-panel-title">{t(`config.panels.${activePanel}`)}</h2>
</div>
<div className="config-panel-body">
{activePanel === 'profile' && (
<PanelProfile

View File

@@ -407,30 +407,14 @@ input::placeholder { color: var(--text-disabled); }
display: flex; justify-content: flex-end; gap: 8px;
}
.config-window { display: flex; height: 100%; overflow: hidden; }
.config-window { display: flex; flex-direction: column; height: 100%; overflow: hidden; }
.config-sidebar {
width: 180px; background: var(--bg-surface); border-right: 1px solid var(--border);
display: flex; flex-direction: column; padding: 12px 8px; gap: 2px; flex-shrink: 0;
overflow-y: auto;
.config-tabs-bar {
display: flex; gap: 4px; padding: 12px 20px 0; background: var(--bg-surface);
border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.config-sidebar-item {
display: flex; align-items: center; gap: 10px; padding: 9px 12px;
border-radius: var(--radius); font-size: 13px; font-weight: 500;
color: var(--text-tertiary); cursor: pointer; transition: all 0.15s;
user-select: none;
}
.config-sidebar-item:hover { background: var(--bg-card); color: var(--text-primary); }
.config-sidebar-item.active { background: var(--accent-bg); color: var(--accent); font-weight: 600; }
.config-sidebar-item svg { flex-shrink: 0; }
.config-panel-area { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.config-panel-header {
padding: 20px 28px 0; flex-shrink: 0;
}
.config-panel-title {
font-size: 16px; font-weight: 700; color: var(--text-primary); margin: 0;
}
.config-panel-body { flex: 1; overflow-y: auto; padding: 16px 28px 28px; }
.config-card {
@@ -605,3 +589,45 @@ input::placeholder { color: var(--text-disabled); }
.feed-content { font-size: 14px; line-height: 1.7; color: var(--text-primary); word-break: break-word; }
.feed-system-badge { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-dim); flex-shrink: 0; }
.feed-system-text { font-size: 12px; color: var(--text-tertiary); font-style: italic; flex: 1; }
.studio-code-block {
background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius);
overflow: hidden; margin: 8px 0;
}
.studio-code-block pre { padding: 12px 16px; font-family: var(--font-mono); font-size: 13px; line-height: 1.5; overflow-x: auto; color: var(--text-primary); margin: 0; }
.studio-code-lang {
padding: 4px 12px; font-size: 11px; font-weight: 600; color: var(--text-tertiary);
background: var(--bg-surface); border-bottom: 1px solid var(--border); text-transform: uppercase; letter-spacing: 0.5px;
}
.inline-code { background: var(--bg-input); padding: 2px 6px; border-radius: 4px; font-family: var(--font-mono); font-size: 13px; color: var(--accent-muted); }
.msg-h3 { font-size: 16px; font-weight: 700; color: var(--text-primary); margin: 16px 0 8px; display: block; }
.msg-h4 { font-size: 14px; font-weight: 700; color: var(--text-secondary); margin: 12px 0 6px; display: block; }
.msg-bullet { display: block; padding-left: 16px; position: relative; margin: 2px 0; }
.msg-bullet::before { content: '\2022'; position: absolute; left: 4px; color: var(--accent); }
.msg-step { display: flex; gap: 8px; align-items: baseline; margin: 3px 0; }
.msg-step-num { color: var(--accent); font-weight: 700; font-family: var(--font-mono); font-size: 13px; flex-shrink: 0; min-width: 20px; }
.studio-cursor { display: inline-block; width: 8px; height: 16px; background: var(--accent); margin-left: 2px; vertical-align: text-bottom; animation: blink 0.8s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
.studio-thinking { display: flex; gap: 4px; padding: 8px 0; }
.studio-thinking span { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-dim); animation: bounce 1.2s ease-in-out infinite; }
.studio-thinking span:nth-child(2) { animation-delay: 0.15s; }
.studio-thinking span:nth-child(3) { animation-delay: 0.3s; }
@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); opacity: 0.4; } 40% { transform: translateY(-6px); opacity: 1; } }
.studio-input-area { padding: 12px 20px 8px; border-top: 1px solid var(--border); background: var(--bg-surface); }
.studio-input-row { display: flex; gap: 8px; align-items: flex-end; }
.studio-input-row textarea {
flex: 1; resize: none; min-height: 42px; max-height: 200px; padding: 10px 14px;
font-size: 14px; line-height: 1.5; border-radius: var(--radius);
background: var(--bg-input); color: var(--text-primary); border: 1px solid var(--border);
font-family: var(--font-sans); outline: none; transition: border-color 0.2s, box-shadow 0.2s;
}
.studio-input-row textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--border-accent); }
.studio-input-row textarea::placeholder { color: var(--text-disabled); }
.studio-send-btn {
width: 42px; height: 42px; padding: 0; display: flex; align-items: center; justify-content: center;
border-radius: var(--radius); background: var(--accent); color: #fff; border: 1px solid var(--accent);
cursor: pointer; transition: all 0.15s; flex-shrink: 0;
}
.studio-send-btn:hover:not(:disabled) { background: var(--accent-bright); border-color: var(--accent-bright); }
.studio-send-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.studio-input-hint { font-size: 11px; color: var(--text-disabled); text-align: center; margin-top: 6px; }