mdk-skills 2.4.0 → 2.4.2
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.
- package/package.json +4 -2
- package/scripts/web-ui/dist/assets/index-B5lUvD80.css +1 -0
- package/scripts/web-ui/dist/assets/{index-Bu8b9gwQ.js → index-c2voeFwQ.js} +2 -2
- package/scripts/web-ui/dist/index.html +2 -2
- package/scripts/web-ui/dist/assets/index-CfvkkgtO.css +0 -1
- package/scripts/web-ui/index.html +0 -15
- package/scripts/web-ui/src/App.vue +0 -195
- package/scripts/web-ui/src/api/skills.js +0 -207
- package/scripts/web-ui/src/components/ModalComp.vue +0 -182
- package/scripts/web-ui/src/components/SkillCard.vue +0 -99
- package/scripts/web-ui/src/components/StatusBar.vue +0 -87
- package/scripts/web-ui/src/main.js +0 -10
- package/scripts/web-ui/src/router/index.js +0 -17
- package/scripts/web-ui/src/styles/main.css +0 -352
- package/scripts/web-ui/src/utils/usage.js +0 -46
- package/scripts/web-ui/src/views/Dashboard.vue +0 -1697
- package/scripts/web-ui/src/views/ReadmeView.vue +0 -115
- package/scripts/web-ui/src/views/SceneSwitch.vue +0 -1361
- package/scripts/web-ui/src/views/Settings.vue +0 -529
- package/scripts/web-ui/vite.config.js +0 -11
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="settings">
|
|
3
|
-
<div class="page-header">
|
|
4
|
-
<h2>设置</h2>
|
|
5
|
-
</div>
|
|
6
|
-
|
|
7
|
-
<!-- 技能目录管理 -->
|
|
8
|
-
<n-card title="技能目录" size="small" class="section">
|
|
9
|
-
<div class="source-status">
|
|
10
|
-
<n-alert v-if="sourceInfo.connected" type="success" :bordered="false">
|
|
11
|
-
<template #header>已设置</template>
|
|
12
|
-
{{ sourceInfo.path }}
|
|
13
|
-
</n-alert>
|
|
14
|
-
<n-alert v-else type="warning" :bordered="false">
|
|
15
|
-
尚未设置技能目录,请指定包含 .claude/skills 的仓库路径
|
|
16
|
-
</n-alert>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<!-- 初始化提示 -->
|
|
20
|
-
<n-alert v-if="sourceInfo.connected && sourceInfo.needsInit" type="warning" :bordered="false" class="init-alert">
|
|
21
|
-
<template #header>技能目录缺少必要文件</template>
|
|
22
|
-
<div class="missing-list">
|
|
23
|
-
<template v-if="sourceInfo.missingConfig?.length">
|
|
24
|
-
<div class="missing-item" v-for="f in sourceInfo.missingConfig" :key="f">
|
|
25
|
-
缺少配置文件:<code>{{ f }}</code>
|
|
26
|
-
</div>
|
|
27
|
-
</template>
|
|
28
|
-
<template v-if="sourceInfo.missingSkillDocs?.length">
|
|
29
|
-
<div class="missing-item">
|
|
30
|
-
以下技能缺少 SKILL.md 文档:
|
|
31
|
-
<code v-for="name in sourceInfo.missingSkillDocs" :key="name" class="skill-tag">{{ name }}</code>
|
|
32
|
-
</div>
|
|
33
|
-
</template>
|
|
34
|
-
<div class="missing-hint">可手动检测该文件夹是否为skill,若该目录不是 skill,可手动删除</div>
|
|
35
|
-
</div>
|
|
36
|
-
</n-alert>
|
|
37
|
-
|
|
38
|
-
<div class="source-actions">
|
|
39
|
-
<n-input
|
|
40
|
-
v-if="!sourceInfo.connected"
|
|
41
|
-
v-model:value="repoPath"
|
|
42
|
-
placeholder="输入本地仓库路径..."
|
|
43
|
-
clearable
|
|
44
|
-
>
|
|
45
|
-
<template #prefix>📁</template>
|
|
46
|
-
</n-input>
|
|
47
|
-
|
|
48
|
-
<!-- 独立于 init:仅 README.md 缺失时的创建入口 -->
|
|
49
|
-
<n-alert
|
|
50
|
-
v-if="sourceInfo.connected && sourceInfo.needsInit === false && hasReadmeMissing"
|
|
51
|
-
type="info"
|
|
52
|
-
:bordered="false"
|
|
53
|
-
class="init-alert"
|
|
54
|
-
>
|
|
55
|
-
<template #header>缺少 README.md 文档</template>
|
|
56
|
-
创建后将生成模板文件,可在对应目录中自行编辑
|
|
57
|
-
</n-alert>
|
|
58
|
-
|
|
59
|
-
<div class="action-buttons">
|
|
60
|
-
<n-button
|
|
61
|
-
v-if="!sourceInfo.connected"
|
|
62
|
-
type="primary"
|
|
63
|
-
:disabled="!repoPath"
|
|
64
|
-
:loading="connecting"
|
|
65
|
-
@click="onConnect"
|
|
66
|
-
>
|
|
67
|
-
设置
|
|
68
|
-
</n-button>
|
|
69
|
-
<n-button
|
|
70
|
-
v-if="sourceInfo.connected && sourceInfo.needsInit"
|
|
71
|
-
type="warning"
|
|
72
|
-
:loading="initializing"
|
|
73
|
-
@click="onInit"
|
|
74
|
-
>
|
|
75
|
-
初始化
|
|
76
|
-
</n-button>
|
|
77
|
-
<n-button
|
|
78
|
-
v-if="sourceInfo.connected"
|
|
79
|
-
:loading="syncing"
|
|
80
|
-
@click="onSync"
|
|
81
|
-
>
|
|
82
|
-
同步到仓库
|
|
83
|
-
</n-button>
|
|
84
|
-
<n-button
|
|
85
|
-
v-if="sourceInfo.connected && sourceInfo.needsInit === false && hasReadmeMissing"
|
|
86
|
-
ghost
|
|
87
|
-
@click="onShowCreateReadme"
|
|
88
|
-
>
|
|
89
|
-
创建文档
|
|
90
|
-
</n-button>
|
|
91
|
-
<n-button
|
|
92
|
-
v-if="sourceInfo.connected"
|
|
93
|
-
type="error"
|
|
94
|
-
ghost
|
|
95
|
-
:loading="disconnecting"
|
|
96
|
-
@click="onDisconnect"
|
|
97
|
-
>
|
|
98
|
-
清除
|
|
99
|
-
</n-button>
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
</n-card>
|
|
103
|
-
|
|
104
|
-
<!-- 创建 README.md 对话框 -->
|
|
105
|
-
<ModalComp
|
|
106
|
-
:show="showReadmeDialog"
|
|
107
|
-
title="创建文档"
|
|
108
|
-
width="520px"
|
|
109
|
-
:mask-closable="false"
|
|
110
|
-
@update:show="(v) => { if (!v) showReadmeDialog = false }"
|
|
111
|
-
>
|
|
112
|
-
<div class="readme-dialog-desc">检测到缺少以下文档,是否创建?</div>
|
|
113
|
-
|
|
114
|
-
<n-checkbox v-model:checked="readmeForm.root" class="readme-checkbox">
|
|
115
|
-
<div class="readme-checkbox-content">
|
|
116
|
-
<span class="readme-checkbox-title">根目录 README.md</span>
|
|
117
|
-
<span class="readme-checkbox-desc">仪表盘 → "仓库说明"折叠面板,适合写项目简介、维护团队、许可证</span>
|
|
118
|
-
</div>
|
|
119
|
-
</n-checkbox>
|
|
120
|
-
|
|
121
|
-
<n-checkbox v-model:checked="readmeForm.skills" class="readme-checkbox">
|
|
122
|
-
<div class="readme-checkbox-content">
|
|
123
|
-
<span class="readme-checkbox-title">.claude/skills/README.md</span>
|
|
124
|
-
<span class="readme-checkbox-desc">场景切换 → "技能说明"折叠面板,适合写使用指南、场景搭配建议</span>
|
|
125
|
-
</div>
|
|
126
|
-
</n-checkbox>
|
|
127
|
-
|
|
128
|
-
<n-divider />
|
|
129
|
-
|
|
130
|
-
<n-form label-placement="top">
|
|
131
|
-
<n-form-item label="项目名称(选填)">
|
|
132
|
-
<n-input v-model:value="readmeForm.projectName" placeholder="我的技能仓库" />
|
|
133
|
-
</n-form-item>
|
|
134
|
-
<n-form-item label="维护团队(选填)">
|
|
135
|
-
<n-input v-model:value="readmeForm.teamName" placeholder="未设定" />
|
|
136
|
-
</n-form-item>
|
|
137
|
-
</n-form>
|
|
138
|
-
|
|
139
|
-
<template #footer>
|
|
140
|
-
<n-button @click="showReadmeDialog = false">跳过</n-button>
|
|
141
|
-
<n-button type="primary" :loading="creatingReadme" @click="onCreateReadme">
|
|
142
|
-
创建
|
|
143
|
-
</n-button>
|
|
144
|
-
</template>
|
|
145
|
-
</ModalComp>
|
|
146
|
-
|
|
147
|
-
<!-- 健康检查 -->
|
|
148
|
-
<n-card title="健康检查" size="small" class="section">
|
|
149
|
-
<template #header-extra>
|
|
150
|
-
<n-button size="tiny" :loading="diagnosing" @click="onDiagnose">
|
|
151
|
-
运行检查
|
|
152
|
-
</n-button>
|
|
153
|
-
</template>
|
|
154
|
-
|
|
155
|
-
<n-spin :show="diagnosing">
|
|
156
|
-
<n-empty v-if="!diagnosis.length && !diagnosing" description="点击按钮运行健康检查" />
|
|
157
|
-
<template v-else>
|
|
158
|
-
<div v-if="groupedDiagnosis.unhealthy.length > 0" class="diag-group">
|
|
159
|
-
<div class="diag-group-header diag-group-error">
|
|
160
|
-
<CloseCircleOutline size="24" />
|
|
161
|
-
异常({{ groupedDiagnosis.unhealthy.length }})
|
|
162
|
-
</div>
|
|
163
|
-
<n-list>
|
|
164
|
-
<n-list-item v-for="item in groupedDiagnosis.unhealthy" :key="item.name">
|
|
165
|
-
<template #prefix>
|
|
166
|
-
<n-icon size="20" color="#d03050">
|
|
167
|
-
<CloseCircleOutline />
|
|
168
|
-
</n-icon>
|
|
169
|
-
</template>
|
|
170
|
-
<n-text>{{ item.name }}</n-text>
|
|
171
|
-
<template #suffix>
|
|
172
|
-
<n-text depth="3" class="issue-text">{{ item.issues.join("; ") }}</n-text>
|
|
173
|
-
</template>
|
|
174
|
-
</n-list-item>
|
|
175
|
-
</n-list>
|
|
176
|
-
</div>
|
|
177
|
-
<div v-if="groupedDiagnosis.healthy.length > 0" class="diag-group">
|
|
178
|
-
<div class="diag-group-header diag-group-ok">
|
|
179
|
-
<CheckmarkCircleOutline />
|
|
180
|
-
正常({{ groupedDiagnosis.healthy.length }})
|
|
181
|
-
</div>
|
|
182
|
-
<n-list>
|
|
183
|
-
<n-list-item v-for="item in groupedDiagnosis.healthy" :key="item.name">
|
|
184
|
-
<template #prefix>
|
|
185
|
-
<n-icon size="20" color="#18a058">
|
|
186
|
-
<CheckmarkCircleOutline />
|
|
187
|
-
</n-icon>
|
|
188
|
-
</template>
|
|
189
|
-
<n-text>{{ item.name }}</n-text>
|
|
190
|
-
<template #suffix>
|
|
191
|
-
<n-text depth="3" class="healthy-text">正常</n-text>
|
|
192
|
-
</template>
|
|
193
|
-
</n-list-item>
|
|
194
|
-
</n-list>
|
|
195
|
-
</div>
|
|
196
|
-
</template>
|
|
197
|
-
</n-spin>
|
|
198
|
-
</n-card>
|
|
199
|
-
</div>
|
|
200
|
-
</template>
|
|
201
|
-
|
|
202
|
-
<script setup>
|
|
203
|
-
import { ref, computed, onMounted } from "vue";
|
|
204
|
-
import { useMessage } from "naive-ui";
|
|
205
|
-
import ModalComp from "../components/ModalComp.vue";
|
|
206
|
-
import {
|
|
207
|
-
CheckmarkCircleOutline,
|
|
208
|
-
CloseCircleOutline,
|
|
209
|
-
} from "@vicons/ionicons5";
|
|
210
|
-
import {
|
|
211
|
-
getSource,
|
|
212
|
-
connectSource,
|
|
213
|
-
clearSource,
|
|
214
|
-
syncSource,
|
|
215
|
-
initSource,
|
|
216
|
-
diagnose,
|
|
217
|
-
createReadme,
|
|
218
|
-
} from "../api/skills";
|
|
219
|
-
|
|
220
|
-
const emit = defineEmits(["refresh"]);
|
|
221
|
-
const message = useMessage();
|
|
222
|
-
|
|
223
|
-
const sourceInfo = ref({ connected: false, path: null, needsInit: false });
|
|
224
|
-
const repoPath = ref("");
|
|
225
|
-
const connecting = ref(false);
|
|
226
|
-
const initializing = ref(false);
|
|
227
|
-
const syncing = ref(false);
|
|
228
|
-
const disconnecting = ref(false);
|
|
229
|
-
const diagnosing = ref(false);
|
|
230
|
-
const diagnosis = ref([]);
|
|
231
|
-
|
|
232
|
-
const groupedDiagnosis = computed(() => {
|
|
233
|
-
const healthy = [];
|
|
234
|
-
const unhealthy = [];
|
|
235
|
-
for (const item of diagnosis.value) {
|
|
236
|
-
if (item.healthy) healthy.push(item);
|
|
237
|
-
else unhealthy.push(item);
|
|
238
|
-
}
|
|
239
|
-
return { healthy, unhealthy };
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// 创建 README.md 对话框
|
|
243
|
-
const showReadmeDialog = ref(false);
|
|
244
|
-
const creatingReadme = ref(false);
|
|
245
|
-
const readmeForm = ref({
|
|
246
|
-
root: true,
|
|
247
|
-
skills: true,
|
|
248
|
-
projectName: "",
|
|
249
|
-
teamName: "",
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const hasReadmeMissing = computed(() => {
|
|
253
|
-
if (!sourceInfo.value.readmeStatus) return false;
|
|
254
|
-
return !sourceInfo.value.readmeStatus.root || !sourceInfo.value.readmeStatus.skills;
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
async function loadSource() {
|
|
258
|
-
sourceInfo.value = await getSource();
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
async function onConnect() {
|
|
262
|
-
connecting.value = true;
|
|
263
|
-
try {
|
|
264
|
-
const res = await connectSource(repoPath.value);
|
|
265
|
-
if (res.ok) {
|
|
266
|
-
message.success("技能目录已设置");
|
|
267
|
-
await loadSource();
|
|
268
|
-
emit("refresh");
|
|
269
|
-
} else {
|
|
270
|
-
message.error(res.error || "设置失败");
|
|
271
|
-
}
|
|
272
|
-
} catch {
|
|
273
|
-
message.error("设置失败");
|
|
274
|
-
} finally {
|
|
275
|
-
connecting.value = false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async function onSync() {
|
|
280
|
-
syncing.value = true;
|
|
281
|
-
try {
|
|
282
|
-
const res = await syncSource();
|
|
283
|
-
if (res.ok) {
|
|
284
|
-
message.success("已同步到仓库");
|
|
285
|
-
} else {
|
|
286
|
-
message.error(res.error || "同步失败");
|
|
287
|
-
}
|
|
288
|
-
} catch {
|
|
289
|
-
message.error("同步失败");
|
|
290
|
-
} finally {
|
|
291
|
-
syncing.value = false;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
async function onInit() {
|
|
296
|
-
initializing.value = true;
|
|
297
|
-
try {
|
|
298
|
-
const res = await initSource();
|
|
299
|
-
if (res.ok) {
|
|
300
|
-
const parts = [];
|
|
301
|
-
if (res.profiles) parts.push("profiles.json");
|
|
302
|
-
if (res.settings) parts.push("settings.json");
|
|
303
|
-
if (res.metaFiles > 0) parts.push(`${res.metaFiles} 个 .meta.json`);
|
|
304
|
-
message.success(`初始化完成:${parts.join("、") || "无缺失文件"}`);
|
|
305
|
-
|
|
306
|
-
// 检测 README.md 缺失情况,弹创建对话框
|
|
307
|
-
if (res.readmeStatus) {
|
|
308
|
-
const anyMissing = !res.readmeStatus.root || !res.readmeStatus.skills;
|
|
309
|
-
if (anyMissing) {
|
|
310
|
-
readmeForm.value.root = !res.readmeStatus.root;
|
|
311
|
-
readmeForm.value.skills = !res.readmeStatus.skills;
|
|
312
|
-
showReadmeDialog.value = true;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
await loadSource();
|
|
317
|
-
emit("refresh");
|
|
318
|
-
} else {
|
|
319
|
-
message.error(res.error || "初始化失败");
|
|
320
|
-
}
|
|
321
|
-
} catch {
|
|
322
|
-
message.error("初始化失败");
|
|
323
|
-
} finally {
|
|
324
|
-
initializing.value = false;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
async function onCreateReadme() {
|
|
329
|
-
creatingReadme.value = true;
|
|
330
|
-
try {
|
|
331
|
-
const res = await createReadme({
|
|
332
|
-
root: readmeForm.value.root,
|
|
333
|
-
skills: readmeForm.value.skills,
|
|
334
|
-
projectName: readmeForm.value.projectName.trim(),
|
|
335
|
-
teamName: readmeForm.value.teamName.trim(),
|
|
336
|
-
});
|
|
337
|
-
if (res.ok) {
|
|
338
|
-
const parts = res.created || [];
|
|
339
|
-
message.success(`已创建:${parts.join("、") || "无"}`);
|
|
340
|
-
showReadmeDialog.value = false;
|
|
341
|
-
} else {
|
|
342
|
-
message.error(res.error || "创建失败");
|
|
343
|
-
}
|
|
344
|
-
} catch {
|
|
345
|
-
message.error("创建失败");
|
|
346
|
-
} finally {
|
|
347
|
-
creatingReadme.value = false;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function onShowCreateReadme() {
|
|
352
|
-
readmeForm.value.root = !sourceInfo.value.readmeStatus?.root;
|
|
353
|
-
readmeForm.value.skills = !sourceInfo.value.readmeStatus?.skills;
|
|
354
|
-
showReadmeDialog.value = true;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
async function onDisconnect() {
|
|
358
|
-
disconnecting.value = true;
|
|
359
|
-
try {
|
|
360
|
-
const res = await clearSource();
|
|
361
|
-
if (res.ok) {
|
|
362
|
-
message.success("技能目录已清除");
|
|
363
|
-
await loadSource();
|
|
364
|
-
emit("refresh");
|
|
365
|
-
}
|
|
366
|
-
} catch {
|
|
367
|
-
message.error("清除失败");
|
|
368
|
-
} finally {
|
|
369
|
-
disconnecting.value = false;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async function onDiagnose() {
|
|
374
|
-
diagnosing.value = true;
|
|
375
|
-
try {
|
|
376
|
-
diagnosis.value = await diagnose();
|
|
377
|
-
} catch {
|
|
378
|
-
message.error("诊断失败");
|
|
379
|
-
} finally {
|
|
380
|
-
diagnosing.value = false;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
onMounted(loadSource);
|
|
385
|
-
</script>
|
|
386
|
-
|
|
387
|
-
<style scoped>
|
|
388
|
-
.page-header {
|
|
389
|
-
margin-bottom: 20px;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
.page-header h2 {
|
|
393
|
-
font-size: 20px;
|
|
394
|
-
font-weight: 600;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.section {
|
|
398
|
-
margin-bottom: 20px;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
.init-alert {
|
|
402
|
-
margin-bottom: 12px;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
.missing-list {
|
|
406
|
-
display: flex;
|
|
407
|
-
flex-direction: column;
|
|
408
|
-
gap: 4px;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
.missing-item {
|
|
412
|
-
font-size: 13px;
|
|
413
|
-
line-height: 1.6;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
.missing-item code {
|
|
417
|
-
font-size: 12px;
|
|
418
|
-
background: rgba(0, 0, 0, 0.06);
|
|
419
|
-
padding: 1px 6px;
|
|
420
|
-
border-radius: 3px;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
.skill-tag {
|
|
424
|
-
display: inline-block;
|
|
425
|
-
margin: 1px 2px;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
.missing-hint {
|
|
429
|
-
margin-top: 4px;
|
|
430
|
-
font-size: 12px;
|
|
431
|
-
opacity: 0.7;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
.source-status {
|
|
435
|
-
margin-bottom: 16px;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
.source-actions {
|
|
439
|
-
display: flex;
|
|
440
|
-
flex-direction: column;
|
|
441
|
-
gap: 12px;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
.action-buttons {
|
|
445
|
-
display: flex;
|
|
446
|
-
gap: 8px;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
.healthy-text {
|
|
450
|
-
color: #18a058;
|
|
451
|
-
font-size: 13px;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
.issue-text {
|
|
455
|
-
color: #d03050;
|
|
456
|
-
font-size: 13px;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
.readme-dialog-desc {
|
|
460
|
-
margin-bottom: 16px;
|
|
461
|
-
font-size: 14px;
|
|
462
|
-
color: #555;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
.readme-checkbox {
|
|
466
|
-
display: flex;
|
|
467
|
-
align-items: flex-start;
|
|
468
|
-
margin-bottom: 12px;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
.readme-checkbox-content {
|
|
472
|
-
display: flex;
|
|
473
|
-
flex-direction: column;
|
|
474
|
-
gap: 2px;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
.readme-checkbox-title {
|
|
478
|
-
font-size: 14px;
|
|
479
|
-
font-weight: 500;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.readme-checkbox-desc {
|
|
483
|
-
font-size: 12px;
|
|
484
|
-
color: #999;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
.diag-group {
|
|
488
|
-
margin-bottom: 16px;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
.diag-group:last-child {
|
|
492
|
-
margin-bottom: 0;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
.diag-group-header {
|
|
496
|
-
display: flex;
|
|
497
|
-
align-items: center;
|
|
498
|
-
gap: 6px;
|
|
499
|
-
font-size: 13px;
|
|
500
|
-
font-weight: 600;
|
|
501
|
-
padding: 6px 0;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
.diag-group-error {
|
|
505
|
-
color: #d03050;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
.diag-group-ok {
|
|
509
|
-
color: #18a058;
|
|
510
|
-
}
|
|
511
|
-
</style>
|
|
512
|
-
|
|
513
|
-
<style>
|
|
514
|
-
[data-theme="dark"] .missing-item code {
|
|
515
|
-
background: rgba(255, 255, 255, 0.08);
|
|
516
|
-
}
|
|
517
|
-
[data-theme="dark"] .healthy-text {
|
|
518
|
-
color: #4ade80;
|
|
519
|
-
}
|
|
520
|
-
[data-theme="dark"] .issue-text {
|
|
521
|
-
color: #f87171;
|
|
522
|
-
}
|
|
523
|
-
[data-theme="dark"] .readme-dialog-desc {
|
|
524
|
-
color: #a6adc8;
|
|
525
|
-
}
|
|
526
|
-
[data-theme="dark"] .readme-checkbox-desc {
|
|
527
|
-
color: #6c7086;
|
|
528
|
-
}
|
|
529
|
-
</style>
|