mdk-skills 2.2.16 → 2.2.18
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
CHANGED
|
@@ -149,6 +149,39 @@ body {
|
|
|
149
149
|
transition: opacity 0.2s;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
/* ---------- 手搓折叠 ---------- */
|
|
153
|
+
.readme-fold {
|
|
154
|
+
margin-bottom: 20px;
|
|
155
|
+
border: 1px solid #e5e7eb;
|
|
156
|
+
border-radius: 6px;
|
|
157
|
+
overflow: hidden;
|
|
158
|
+
}
|
|
159
|
+
.fold-header {
|
|
160
|
+
display: flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
gap: 6px;
|
|
163
|
+
padding: 10px 16px;
|
|
164
|
+
font-size: 14px;
|
|
165
|
+
font-weight: 600;
|
|
166
|
+
background: #fafafa;
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
user-select: none;
|
|
169
|
+
}
|
|
170
|
+
.fold-header:hover {
|
|
171
|
+
background: #f0f0f0;
|
|
172
|
+
}
|
|
173
|
+
.fold-arrow {
|
|
174
|
+
font-size: 11px;
|
|
175
|
+
transition: transform 0.2s;
|
|
176
|
+
color: #999;
|
|
177
|
+
}
|
|
178
|
+
.fold-arrow.open {
|
|
179
|
+
transform: rotate(90deg);
|
|
180
|
+
}
|
|
181
|
+
.fold-body {
|
|
182
|
+
padding: 0 16px 16px;
|
|
183
|
+
}
|
|
184
|
+
|
|
152
185
|
.markdown-content pre:hover .copy-btn {
|
|
153
186
|
opacity: 1;
|
|
154
187
|
}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="dashboard">
|
|
3
3
|
<!-- 仓库 README -->
|
|
4
|
-
<
|
|
5
|
-
<
|
|
4
|
+
<div class="readme-fold" v-if="readmeContent">
|
|
5
|
+
<div class="fold-header" @click="readmeOpen = !readmeOpen">
|
|
6
|
+
<span class="fold-arrow" :class="{ open: readmeOpen }">▶</span>
|
|
7
|
+
仓库说明
|
|
8
|
+
</div>
|
|
9
|
+
<div class="fold-body" v-show="readmeOpen">
|
|
6
10
|
<div class="markdown-content" v-html="renderedReadme" />
|
|
7
|
-
</
|
|
8
|
-
</
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
9
13
|
|
|
10
14
|
<div class="page-header">
|
|
11
15
|
<h2>技能列表</h2>
|
|
12
16
|
<n-button size="small" @click="loadSkills">
|
|
13
|
-
<template #icon
|
|
17
|
+
<template #icon
|
|
18
|
+
><n-icon><RefreshOutline /></n-icon
|
|
19
|
+
></template>
|
|
14
20
|
刷新
|
|
15
21
|
</n-button>
|
|
16
22
|
</div>
|
|
@@ -38,14 +44,18 @@
|
|
|
38
44
|
v-model:show="detailVisible"
|
|
39
45
|
:title="detailSkill?.name || '技能详情'"
|
|
40
46
|
preset="card"
|
|
41
|
-
style="width: 720px
|
|
47
|
+
style="width: 720px"
|
|
42
48
|
content-style="max-height: 65vh; overflow-y: auto; padding: 16px 24px; background: #fff;"
|
|
43
49
|
:mask-closable="true"
|
|
44
50
|
>
|
|
45
51
|
<div v-if="detailLoading" class="detail-status">
|
|
46
52
|
<n-spin />
|
|
47
53
|
</div>
|
|
48
|
-
<div
|
|
54
|
+
<div
|
|
55
|
+
v-else-if="detailContent"
|
|
56
|
+
class="markdown-content"
|
|
57
|
+
v-html="renderedDetail"
|
|
58
|
+
/>
|
|
49
59
|
<n-empty v-else description="该技能没有 SKILL.md 文档" />
|
|
50
60
|
</n-modal>
|
|
51
61
|
</div>
|
|
@@ -74,8 +84,11 @@ marked.use({
|
|
|
74
84
|
return `<pre><button class="copy-btn" onclick="navigator.clipboard.writeText(this.parentNode.querySelector('code').textContent);this.textContent='已复制';setTimeout(()=>this.textContent='复制',1500)">复制</button><code class="hljs language-${language}">${highlighted}</code></pre>`;
|
|
75
85
|
},
|
|
76
86
|
link({ href, text }) {
|
|
77
|
-
const isExternal =
|
|
78
|
-
|
|
87
|
+
const isExternal =
|
|
88
|
+
href && (href.startsWith("http://") || href.startsWith("https://"));
|
|
89
|
+
const target = isExternal
|
|
90
|
+
? ' target="_blank" rel="noopener noreferrer"'
|
|
91
|
+
: "";
|
|
79
92
|
return `<a href="${href}"${target}>${text}</a>`;
|
|
80
93
|
},
|
|
81
94
|
},
|
|
@@ -88,6 +101,7 @@ const loading = ref(false);
|
|
|
88
101
|
// README
|
|
89
102
|
const readmeContent = ref(null);
|
|
90
103
|
const renderedReadme = ref("");
|
|
104
|
+
const readmeOpen = ref(true);
|
|
91
105
|
|
|
92
106
|
// 详情弹窗
|
|
93
107
|
const detailVisible = ref(false);
|
|
@@ -128,8 +142,8 @@ async function loadReadme() {
|
|
|
128
142
|
try {
|
|
129
143
|
const res = await getReadme();
|
|
130
144
|
if (res.content) {
|
|
131
|
-
readmeContent.value = res.content;
|
|
132
145
|
renderedReadme.value = renderMd(res.content);
|
|
146
|
+
readmeContent.value = res.content;
|
|
133
147
|
}
|
|
134
148
|
} catch {
|
|
135
149
|
// 静默失败
|
|
@@ -189,13 +203,9 @@ onUnmounted(() => document.removeEventListener("visibilitychange", onFocus));
|
|
|
189
203
|
font-weight: 600;
|
|
190
204
|
}
|
|
191
205
|
|
|
192
|
-
.readme-collapse {
|
|
193
|
-
margin-bottom: 20px;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
206
|
.detail-status {
|
|
197
207
|
display: flex;
|
|
198
208
|
justify-content: center;
|
|
199
209
|
padding: 40px 0;
|
|
200
210
|
}
|
|
201
|
-
</style>
|
|
211
|
+
</style>
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="scene-switch">
|
|
3
3
|
<!-- 技能说明文档 -->
|
|
4
|
-
<
|
|
5
|
-
<
|
|
4
|
+
<div class="readme-fold" v-if="skillsReadmeContent">
|
|
5
|
+
<div class="fold-header" @click="skillsReadmeOpen = !skillsReadmeOpen">
|
|
6
|
+
<span class="fold-arrow" :class="{ open: skillsReadmeOpen }">▶</span>
|
|
7
|
+
技能说明
|
|
8
|
+
</div>
|
|
9
|
+
<div class="fold-body" v-show="skillsReadmeOpen">
|
|
6
10
|
<div class="markdown-content" v-html="renderedSkillsReadme" />
|
|
7
|
-
</
|
|
8
|
-
</
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
9
13
|
|
|
10
14
|
<div class="page-header">
|
|
11
15
|
<h2>场景切换</h2>
|
|
12
|
-
<n-button
|
|
13
|
-
|
|
16
|
+
<n-button
|
|
17
|
+
v-if="!readonly"
|
|
18
|
+
size="small"
|
|
19
|
+
type="primary"
|
|
20
|
+
@click="openCreate"
|
|
21
|
+
>
|
|
22
|
+
<template #icon
|
|
23
|
+
><n-icon><AddOutline /></n-icon
|
|
24
|
+
></template>
|
|
14
25
|
新建场景
|
|
15
26
|
</n-button>
|
|
16
27
|
</div>
|
|
@@ -26,9 +37,16 @@
|
|
|
26
37
|
size="small"
|
|
27
38
|
>
|
|
28
39
|
<template #header-extra>
|
|
29
|
-
<n-space
|
|
40
|
+
<n-space
|
|
41
|
+
v-if="
|
|
42
|
+
!readonly && profile.id !== 'custom' && profile.skills !== null
|
|
43
|
+
"
|
|
44
|
+
:size="4"
|
|
45
|
+
>
|
|
30
46
|
<n-button size="tiny" quaternary @click="openEdit(profile)">
|
|
31
|
-
<template #icon
|
|
47
|
+
<template #icon
|
|
48
|
+
><n-icon size="16"><PencilOutline /></n-icon
|
|
49
|
+
></template>
|
|
32
50
|
</n-button>
|
|
33
51
|
<n-popconfirm
|
|
34
52
|
:negative-text="'取消'"
|
|
@@ -37,7 +55,9 @@
|
|
|
37
55
|
>
|
|
38
56
|
<template #trigger>
|
|
39
57
|
<n-button size="tiny" quaternary>
|
|
40
|
-
<template #icon
|
|
58
|
+
<template #icon
|
|
59
|
+
><n-icon size="16"><TrashOutline /></n-icon
|
|
60
|
+
></template>
|
|
41
61
|
</n-button>
|
|
42
62
|
</template>
|
|
43
63
|
确定删除场景「{{ profile.name }}」?
|
|
@@ -82,7 +102,12 @@
|
|
|
82
102
|
</n-spin>
|
|
83
103
|
|
|
84
104
|
<!-- 自定义勾选弹窗 -->
|
|
85
|
-
<n-modal
|
|
105
|
+
<n-modal
|
|
106
|
+
v-model:show="showCustom"
|
|
107
|
+
title="自定义技能组合"
|
|
108
|
+
preset="card"
|
|
109
|
+
style="width: 480px"
|
|
110
|
+
>
|
|
86
111
|
<n-checkbox-group v-model:value="customSelected">
|
|
87
112
|
<n-space vertical>
|
|
88
113
|
<n-checkbox
|
|
@@ -94,7 +119,11 @@
|
|
|
94
119
|
</n-space>
|
|
95
120
|
</n-checkbox-group>
|
|
96
121
|
<template #footer>
|
|
97
|
-
<n-button
|
|
122
|
+
<n-button
|
|
123
|
+
type="primary"
|
|
124
|
+
:loading="customLoading"
|
|
125
|
+
@click="onApplyCustom"
|
|
126
|
+
>
|
|
98
127
|
确认安装
|
|
99
128
|
</n-button>
|
|
100
129
|
</template>
|
|
@@ -197,8 +226,11 @@ marked.use({
|
|
|
197
226
|
return `<pre><button class="copy-btn" onclick="navigator.clipboard.writeText(this.parentNode.querySelector('code').textContent);this.textContent='已复制';setTimeout(()=>this.textContent='复制',1500)">复制</button><code class="hljs language-${language}">${highlighted}</code></pre>`;
|
|
198
227
|
},
|
|
199
228
|
link({ href, text }) {
|
|
200
|
-
const isExternal =
|
|
201
|
-
|
|
229
|
+
const isExternal =
|
|
230
|
+
href && (href.startsWith("http://") || href.startsWith("https://"));
|
|
231
|
+
const target = isExternal
|
|
232
|
+
? ' target="_blank" rel="noopener noreferrer"'
|
|
233
|
+
: "";
|
|
202
234
|
return `<a href="${href}"${target}>${text}</a>`;
|
|
203
235
|
},
|
|
204
236
|
},
|
|
@@ -209,6 +241,7 @@ const message = useMessage();
|
|
|
209
241
|
|
|
210
242
|
// 技能说明 README
|
|
211
243
|
const skillsReadmeContent = ref(null);
|
|
244
|
+
const skillsReadmeOpen = ref(true);
|
|
212
245
|
const renderedSkillsReadme = ref("");
|
|
213
246
|
|
|
214
247
|
const profiles = ref([]);
|
|
@@ -257,8 +290,8 @@ async function loadSkillsReadme() {
|
|
|
257
290
|
try {
|
|
258
291
|
const res = await getSkillsReadme();
|
|
259
292
|
if (res.content) {
|
|
260
|
-
skillsReadmeContent.value = res.content;
|
|
261
293
|
renderedSkillsReadme.value = renderMd(res.content);
|
|
294
|
+
skillsReadmeContent.value = res.content;
|
|
262
295
|
}
|
|
263
296
|
} catch {
|
|
264
297
|
// 静默失败
|
|
@@ -301,7 +334,9 @@ function openEdit(profile) {
|
|
|
301
334
|
}
|
|
302
335
|
|
|
303
336
|
function openCustomDialog() {
|
|
304
|
-
customSelected.value = allSkills.value
|
|
337
|
+
customSelected.value = allSkills.value
|
|
338
|
+
.filter((s) => s.enabled)
|
|
339
|
+
.map((s) => s.name);
|
|
305
340
|
showCustom.value = true;
|
|
306
341
|
}
|
|
307
342
|
|
|
@@ -402,10 +437,6 @@ onMounted(() => {
|
|
|
402
437
|
font-weight: 600;
|
|
403
438
|
}
|
|
404
439
|
|
|
405
|
-
.readme-collapse {
|
|
406
|
-
margin-bottom: 20px;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
440
|
.scene-grid {
|
|
410
441
|
display: grid;
|
|
411
442
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|