Wave 2: 五件套打通全链路(安装/检测/配置/授权/诊断)

- 五个适配器 YAML 全字段补齐(codex/claude-code/gemini/kimi/opencode)
- agentdock-config:TOML/JSON 编解码 + 原子写 + 自动备份
- agentdock-diag:PATH/依赖版本/版本冲突/配置损坏四类规则
- agentdock-core:detectCli/previewAction/runAction 流式/readConfig/writeConfig/authStatus/diagnose
- Tauri IPC 命令 + CLI 详情页/安装确认弹窗/配置表单/诊断页
- cargo test 75 项通过(含 4 项真机 ignored 自测),前端 build 通过
This commit is contained in:
leefer
2026-08-25 08:58:38 +08:00
parent c47494180b
commit 01996a80fe
33 changed files with 9404 additions and 152 deletions
+642
View File
@@ -1173,3 +1173,645 @@ button {
[data-fx-tier="low"] .kpi-card:hover {
transform: none;
}
/* ============================================================
* Wave 2CLI 详情页 / 安装确认弹窗 / 配置表单 / 诊断结果
* 全部颜色/辉光/时长来自 tokens/(视觉规范 v1.2 §3.33.5 + v1.3
* ============================================================ */
/* 授权状态点(未授权 = 紫,静态,不发光不呼吸,§3.3) */
.status-dot.auth {
background: var(--ad-attention);
}
/* ---------- CLI 详情页 ---------- */
.cli-detail {
max-width: var(--ad-frame-max);
margin: 0 auto;
}
.detail-back {
margin-bottom: var(--ad-space-4);
}
.cli-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--ad-space-6);
padding: var(--ad-space-6);
margin-bottom: var(--ad-space-5);
}
.cli-head-main {
display: flex;
align-items: flex-start;
gap: var(--ad-space-4);
min-width: 0;
}
.cli-head-info {
min-width: 0;
display: flex;
flex-direction: column;
gap: var(--ad-space-2);
}
.cli-head-name {
font-size: var(--ad-text-xl-size);
font-weight: var(--ad-text-xl-weight);
}
.cli-head-vendor {
color: var(--ad-text-2);
font-size: var(--ad-text-s-size);
}
.cli-head-license {
color: var(--ad-text-3);
}
.cli-head-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--ad-space-2);
margin-top: var(--ad-space-1);
}
.status-badge-mini {
color: var(--ad-text-2);
font-size: var(--ad-text-xs-size);
}
.cli-head-path {
max-width: 420px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cli-head-unconfirmed {
color: var(--ad-text-3);
font-size: var(--ad-text-xs-size);
}
.cli-head-side {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: var(--ad-space-3);
flex-shrink: 0;
}
.auth-light {
display: inline-flex;
align-items: center;
gap: var(--ad-space-2);
}
.auth-light-text {
color: var(--ad-text-1);
font-size: var(--ad-text-s-size);
}
.cli-head-actions {
display: flex;
align-items: center;
gap: var(--ad-space-3);
}
/* 危险文字按钮(§3.3:卸载 = 文字按钮,悬停变红) */
.btn-text-danger {
display: inline-flex;
align-items: center;
gap: var(--ad-space-2);
height: 36px;
padding: 0 var(--ad-space-2);
border: none;
background: none;
color: var(--ad-text-2);
font-size: var(--ad-text-m-size);
cursor: pointer;
transition: color var(--ad-dur-fast) var(--ad-ease-out);
}
.btn-text-danger:hover:not(:disabled) {
color: var(--ad-danger);
}
.btn-text-danger:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* ---------- 标签页(§3.3:底部 2px 青条 + 青色文字) ---------- */
.tabs {
display: flex;
align-items: center;
gap: var(--ad-space-5);
border-bottom: 1px solid var(--ad-border);
margin-bottom: var(--ad-space-5);
}
.tab {
position: relative;
height: 40px;
padding: 0 var(--ad-space-2);
border: none;
background: none;
color: var(--ad-text-2);
font-size: var(--ad-text-m-size);
cursor: pointer;
transition: color var(--ad-dur-fast) var(--ad-ease-out);
}
.tab:hover {
color: var(--ad-text-1);
}
.tab.active {
color: var(--ad-primary);
}
.tab.active::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: -1px;
height: 2px;
background: var(--ad-primary);
}
.cli-detail-body {
max-width: 720px;
}
/* ---------- 概览 / 文档块 ---------- */
.detail-block {
margin-bottom: var(--ad-space-5);
}
.detail-block-title {
display: flex;
align-items: center;
gap: var(--ad-space-2);
font-size: var(--ad-text-l-size);
font-weight: var(--ad-text-l-weight);
margin-bottom: var(--ad-space-3);
}
.detail-block-text {
color: var(--ad-text-2);
font-size: var(--ad-text-m-size);
line-height: 1.6;
}
.detail-channels {
list-style: none;
display: flex;
flex-direction: column;
gap: var(--ad-space-2);
}
.detail-channel {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--ad-space-2);
}
.detail-channel-pkg {
color: var(--ad-text-2);
font-size: var(--ad-text-xs-size);
}
.detail-note {
display: flex;
align-items: flex-start;
gap: var(--ad-space-2);
color: var(--ad-text-2);
font-size: var(--ad-text-s-size);
padding: var(--ad-space-4);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-m);
background: var(--ad-bg-1);
}
.detail-commands {
list-style: none;
display: flex;
flex-direction: column;
gap: var(--ad-space-3);
}
.detail-command {
display: flex;
align-items: center;
gap: var(--ad-space-3);
}
.detail-command-desc {
color: var(--ad-text-2);
font-size: var(--ad-text-s-size);
}
/* ---------- 诊断结果(§3.5 ---------- */
.diag-summary {
display: flex;
align-items: center;
gap: var(--ad-space-3);
padding: var(--ad-space-4);
margin-bottom: var(--ad-space-4);
background: var(--ad-bg-1);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-m);
font-size: var(--ad-text-m-size);
}
.diag-finding {
display: flex;
align-items: stretch;
margin-bottom: var(--ad-space-3);
background: var(--ad-bg-1);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-m);
overflow: hidden;
}
.diag-sev-bar {
width: 3px;
flex-shrink: 0;
}
.diag-sev-bar.diag-sev-info,
.diag-sev-tag.diag-sev-info {
background: var(--ad-attention);
color: var(--ad-attention);
}
.diag-sev-bar.diag-sev-warn,
.diag-sev-tag.diag-sev-warn {
background: var(--ad-warning);
color: var(--ad-warning);
}
.diag-sev-bar.diag-sev-error,
.diag-sev-tag.diag-sev-error {
background: var(--ad-danger);
color: var(--ad-danger);
}
.diag-finding-body {
flex: 1;
padding: var(--ad-space-4);
display: flex;
flex-direction: column;
gap: var(--ad-space-2);
}
.diag-finding-head {
display: flex;
align-items: center;
gap: var(--ad-space-2);
}
.diag-sev-tag {
display: inline-flex;
align-items: center;
height: 20px;
padding: 0 var(--ad-space-2);
border-radius: var(--ad-radius-s);
font-size: var(--ad-text-xs-size);
background: transparent;
}
.diag-finding-rule {
color: var(--ad-text-3);
font-family: var(--ad-font-mono);
font-size: var(--ad-text-xs-size);
}
.diag-finding-msg {
color: var(--ad-text-1);
font-size: var(--ad-text-m-size);
line-height: 1.5;
}
.diag-evidence-toggle {
align-self: flex-start;
}
.diag-evidence {
padding: var(--ad-space-3);
background: var(--ad-bg-0);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-s);
font-family: var(--ad-font-mono);
font-size: var(--ad-text-xs-size);
color: var(--ad-text-2);
white-space: pre-wrap;
word-break: break-all;
}
/* ---------- 弹窗(§3.6 ---------- */
.modal-mask {
position: fixed;
inset: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
background: var(--ad-modal-mask);
}
.modal {
width: min(560px, calc(100vw - 48px));
max-height: calc(100vh - 96px);
display: flex;
flex-direction: column;
background: var(--ad-bg-2);
border-radius: var(--ad-radius-l);
box-shadow: var(--ad-shadow-pop);
border: 1px solid var(--ad-border);
}
.modal-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--ad-space-4) var(--ad-space-5);
border-bottom: 1px solid var(--ad-border);
}
.modal-title {
font-size: var(--ad-text-l-size);
font-weight: var(--ad-text-l-weight);
}
.modal-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: none;
background: none;
color: var(--ad-text-2);
cursor: pointer;
border-radius: var(--ad-radius-s);
}
.modal-close:hover {
color: var(--ad-text-1);
background: var(--ad-bg-3);
}
.modal-body {
padding: var(--ad-space-5);
overflow-y: auto;
}
.modal-foot {
display: flex;
align-items: center;
justify-content: flex-end;
gap: var(--ad-space-3);
padding: var(--ad-space-4) var(--ad-space-5);
border-top: 1px solid var(--ad-border);
}
/* ---------- 确认弹窗内容 ---------- */
.confirm-body {
display: flex;
flex-direction: column;
gap: var(--ad-space-4);
}
.confirm-section {
display: flex;
flex-direction: column;
gap: var(--ad-space-2);
}
.confirm-label {
color: var(--ad-text-2);
font-size: var(--ad-text-xs-size);
}
.confirm-text {
color: var(--ad-text-1);
font-size: var(--ad-text-m-size);
}
.confirm-empty {
color: var(--ad-text-3);
font-size: var(--ad-text-s-size);
}
.confirm-cmd {
padding: var(--ad-space-3);
background: var(--ad-bg-0);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-s);
overflow-x: auto;
}
.confirm-files {
display: flex;
flex-wrap: wrap;
gap: var(--ad-space-2);
}
.confirm-note {
color: var(--ad-warning);
font-size: var(--ad-text-xs-size);
}
/* ---------- 流式执行日志 ---------- */
.run-log {
display: flex;
flex-direction: column;
gap: var(--ad-space-1);
max-height: 320px;
overflow-y: auto;
font-family: var(--ad-font-mono);
font-size: var(--ad-text-xs-size);
}
.run-log-wait {
display: flex;
align-items: center;
gap: var(--ad-space-2);
color: var(--ad-text-2);
}
.run-log-line {
display: flex;
align-items: flex-start;
gap: var(--ad-space-2);
color: var(--ad-text-2);
word-break: break-all;
white-space: pre-wrap;
}
.run-log-line.step {
color: var(--ad-primary);
}
.run-log-line.stderr {
color: var(--ad-warning);
}
.run-log-line.error {
color: var(--ad-danger);
}
.spin {
animation: ad-spin 1.2s linear infinite;
}
@keyframes ad-spin {
to {
transform: rotate(360deg);
}
}
/* ---------- 配置表单(§3.4 ---------- */
.config-form {
display: flex;
flex-direction: column;
gap: var(--ad-space-5);
max-width: 640px;
}
.field {
display: flex;
flex-direction: column;
gap: var(--ad-space-2);
}
.field-label {
color: var(--ad-text-2);
font-size: var(--ad-text-s-size);
}
.field-required {
color: var(--ad-primary);
}
.field-control {
position: relative;
display: flex;
align-items: center;
}
.field-control input {
width: 100%;
height: 36px;
padding: 0 var(--ad-space-3);
border: 1px solid var(--ad-border);
border-radius: var(--ad-radius-m);
background: var(--ad-bg-0);
color: var(--ad-text-1);
font-size: var(--ad-text-m-size);
outline: none;
transition: border-color var(--ad-dur-micro) var(--ad-ease-out),
box-shadow var(--ad-dur-micro) var(--ad-ease-out);
}
.field-control input::placeholder {
color: var(--ad-text-3);
}
.field-control input:focus {
border-color: var(--ad-primary);
box-shadow: var(--ad-glow-primary);
}
.field-control input[type="password"] {
padding-right: 40px;
}
.field-lock {
position: absolute;
left: var(--ad-space-3);
color: var(--ad-text-2);
pointer-events: none;
}
.field-control .field-lock + input {
padding-left: 32px;
}
.field-eye {
position: absolute;
right: var(--ad-space-2);
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: none;
background: none;
color: var(--ad-text-2);
cursor: pointer;
}
.field-eye:hover {
color: var(--ad-text-1);
}
.field-help {
color: var(--ad-text-2);
font-size: var(--ad-text-xs-size);
}
.field-keyring-note {
color: var(--ad-attention);
}
.config-file-info {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--ad-space-2);
padding-top: var(--ad-space-4);
border-top: 1px solid var(--ad-border);
color: var(--ad-text-2);
font-size: var(--ad-text-xs-size);
}
.config-savebar {
position: sticky;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--ad-space-4);
padding: var(--ad-space-4) 0;
background: linear-gradient(180deg, transparent, var(--ad-bg-0) 40%);
}
.config-save-msg {
display: flex;
flex-direction: column;
gap: var(--ad-space-1);
font-size: var(--ad-text-xs-size);
}
.save-ok {
display: inline-flex;
align-items: center;
gap: var(--ad-space-1);
color: var(--ad-success);
}
.save-detail {
color: var(--ad-text-2);
}
.save-error {
color: var(--ad-danger);
}