mdk-skills 2.3.2 → 2.3.4
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 +1 -1
- package/scripts/web-ui/dist/assets/{index-BnMBIily.js → index-Bq3Or_XK.js} +1531 -1531
- package/scripts/web-ui/dist/assets/index-Dgq5aj-Z.css +1 -0
- package/scripts/web-ui/dist/index.html +2 -2
- package/scripts/web-ui/server.js +54 -20
- package/scripts/web-ui/src/views/Dashboard.vue +130 -13
- package/scripts/web-ui/dist/assets/index-BItq1iGH.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.status-bar[data-v-bc9519f9]{background:#fff;border-bottom:1px solid #e5e7eb;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 24px;display:flex}.status-item[data-v-bc9519f9]{color:#555;align-items:center;gap:6px;font-size:13px;display:flex}.status-item.clickable[data-v-bc9519f9]{cursor:pointer}.status-item.clickable[data-v-bc9519f9]:hover{color:#2080f0}.status-divider[data-v-bc9519f9]{background:#e0e0e0;width:1px;height:20px}[data-theme=dark] .status-bar{background:#1a1a2e;border-bottom-color:#333}[data-theme=dark] .status-item{color:#aaa}[data-theme=dark] .status-divider{background:#333}*{box-sizing:border-box;margin:0;padding:0}html,body,#app{background:#f5f7fa;height:100%}body{overflow-y:auto}*{scrollbar-width:none;-ms-overflow-style:none}::-webkit-scrollbar{display:none}.app-layout{flex-direction:column;min-height:100vh;padding-top:56px;display:flex}.app-header{z-index:100;background:#fff;border-bottom:1px solid #e5e7eb;align-items:center;height:56px;padding:0 24px;display:flex;position:fixed;top:0;left:0;right:0}.header-inner{justify-content:space-between;align-items:center;width:100%;display:flex}.header-left{align-items:center;gap:32px;display:flex}.logo{color:#1a1a1a;white-space:nowrap;font-size:18px;font-weight:700}.app-content{flex:1;width:100%;max-width:1000px;margin:0 auto;padding:24px}.markdown-content{color:#333;word-wrap:break-word;font-size:14px;line-height:1.7}.markdown-content h1{border-bottom:1px solid #eee;margin:20px 0 12px;padding-bottom:8px;font-size:22px;font-weight:700}.markdown-content h2{border-bottom:1px solid #eee;margin:18px 0 10px;padding-bottom:6px;font-size:18px;font-weight:700}.markdown-content h3{margin:16px 0 8px;font-size:16px;font-weight:600}.markdown-content h4{margin:14px 0 6px;font-size:14px;font-weight:600}.markdown-content h5,.markdown-content h6{margin:12px 0 6px;font-size:13px;font-weight:600}.markdown-content p{margin:8px 0}.markdown-content ul,.markdown-content ol{margin:8px 0;padding-left:24px}.markdown-content li{margin:4px 0}.markdown-content blockquote{color:#555;background:#f0f7ff;border-left:4px solid #2080f0;margin:10px 0;padding:8px 16px}.markdown-content blockquote p{margin:4px 0}.markdown-content a{color:#2080f0;text-decoration:none}.markdown-content a:hover{text-decoration:underline}.markdown-content hr{border:none;border-top:1px solid #e0e0e0;margin:16px 0}.markdown-content table{border-collapse:collapse;width:100%;margin:12px 0;font-size:13px}.markdown-content th,.markdown-content td{text-align:left;border:1px solid #e0e0e0;padding:8px 12px}.markdown-content th{background:#f5f7fa;font-weight:600}.markdown-content tr:nth-child(2n) td{background:#fafafa}.markdown-content img{border-radius:4px;max-width:100%;margin:8px 0}.markdown-content code{color:#d63384;background:#f0f0f0;border-radius:3px;padding:2px 6px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px}.markdown-content pre{border:1px solid #e8e8e8;border-radius:6px;margin:12px 0;padding:0;position:relative;overflow:hidden}.markdown-content pre code{color:#333;tab-size:2;background:#f8f9fa;padding:14px 16px;font-size:13px;line-height:1.5;display:block;overflow-x:auto}.markdown-content pre .copy-btn{color:#999;cursor:pointer;opacity:0;background:#fff;border:1px solid #e0e0e0;border-radius:4px;padding:3px 8px;font-size:11px;transition:opacity .2s;position:absolute;top:6px;right:6px}.readme-fold{border:1px solid #e5e7eb;border-radius:6px;margin-bottom:20px;overflow:hidden}.fold-header{cursor:pointer;-webkit-user-select:none;user-select:none;background:#fafafa;align-items:center;gap:6px;padding:10px 16px;font-size:14px;font-weight:600;display:flex}.fold-header:hover{background:#f0f0f0}.fold-arrow{color:#999;font-size:11px;transition:transform .2s}.fold-arrow.open{transform:rotate(90deg)}.fold-body{padding:0 16px 16px}.markdown-content pre:hover .copy-btn{opacity:1}.markdown-content pre .copy-btn:hover{color:#2080f0;border-color:#2080f0}.header-right{align-items:center;gap:8px;display:flex}[data-theme=dark] html,[data-theme=dark] body,[data-theme=dark] #app{background:#1a1a2e}[data-theme=dark] .app-header{background:#1a1a2e;border-bottom-color:#333}[data-theme=dark] .app-content{background:0 0}[data-theme=dark] .readme-fold{border-color:#333}[data-theme=dark] .fold-header{color:#e0e0e0;background:#252538}[data-theme=dark] .fold-header:hover{background:#2a2a40}[data-theme=dark] .fold-body{background:#1e1e32}[data-theme=dark] .fold-arrow{color:#888}[data-theme=dark] .markdown-content{color:#ccc}[data-theme=dark] .markdown-content h1,[data-theme=dark] .markdown-content h2{color:#eee;border-bottom-color:#333}[data-theme=dark] .markdown-content h3,[data-theme=dark] .markdown-content h4{color:#eee}[data-theme=dark] .markdown-content code{color:#e06c9f;background:#2a2a40}[data-theme=dark] .markdown-content pre{border-color:#333}[data-theme=dark] .markdown-content pre code{color:#d4d4d4;background:#1e1e2e}[data-theme=dark] .markdown-content blockquote{color:#bbb;background:#252538;border-left-color:#4a6cf7}[data-theme=dark] .markdown-content a{color:#6a8cff}[data-theme=dark] .markdown-content th{background:#252538}[data-theme=dark] .markdown-content td{border-color:#333}[data-theme=dark] .markdown-content tr:nth-child(2n) td{background:#222238}[data-theme=dark] .markdown-content hr{border-top-color:#333}[data-theme=dark] .markdown-content img{filter:brightness(.85)}[data-theme=dark] .page-header h2{color:#e0e0e0}[data-theme=dark] .scene-desc{color:#aaa}.fade-enter-active,.fade-leave-active{transition:opacity .9s,transform .9s}.fade-enter-from{opacity:0;transform:translateY(6px)}.fade-leave-to{opacity:0}.skill-card[data-v-f2c0de50]{cursor:pointer;margin-bottom:12px;transition:box-shadow .2s}.skill-card[data-v-f2c0de50]:hover{box-shadow:0 2px 8px #00000014}.skill-meta[data-v-f2c0de50]{align-items:center;gap:8px;margin-bottom:8px;display:flex}.skill-version[data-v-f2c0de50]{color:#888;font-family:monospace;font-size:12px}.skill-desc[data-v-f2c0de50]{color:#666;text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:13px;overflow:hidden}.dashboard[data-v-f712ceef]{overflow-anchor:auto}.page-header[data-v-f712ceef]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;margin-bottom:4px;display:flex}.page-header h2[data-v-f712ceef]{font-size:20px;font-weight:600}.header-actions[data-v-f712ceef]{align-items:center;gap:8px;display:flex}.tag-filter[data-v-f712ceef]{flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:16px;display:flex}.detail-status[data-v-f712ceef]{justify-content:center;padding:40px 0;display:flex}.detail-body[data-v-f712ceef]{max-height:65vh;padding:16px 24px;overflow-y:auto}.edit-panel[data-v-f712ceef]{margin-bottom:4px}.edit-row[data-v-f712ceef]{align-items:flex-start;gap:10px;margin-bottom:10px;display:flex}.edit-label[data-v-f712ceef]{color:#888;flex-shrink:0;width:50px;font-size:13px;line-height:30px}.update-count-hint[data-v-f712ceef]{color:#e68a00;margin-left:8px;font-family:monospace;font-size:12px}.pull-modal-body[data-v-f712ceef]{min-height:100px}.pull-section[data-v-f712ceef]{margin-top:12px}.pull-input-row[data-v-f712ceef]{gap:8px;margin-bottom:8px;display:flex}.pull-input-row .n-input[data-v-f712ceef]{flex:1}.pull-error[data-v-f712ceef]{margin-bottom:8px}.pull-result[data-v-f712ceef]{margin-top:8px}.pull-result-line[data-v-f712ceef]{flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:8px;font-size:13px;display:flex}.pull-result-label[data-v-f712ceef]{color:#888;flex-shrink:0}.pull-result-hint[data-v-f712ceef]{color:#999;font-size:12px}.install-panel[data-v-f712ceef]{background:#00000005;border-radius:6px;margin-top:12px;padding:12px}.install-panel-label[data-v-f712ceef]{color:#666;margin-bottom:8px;font-size:13px}.install-check-list[data-v-f712ceef]{margin-bottom:10px}.install-btn[data-v-f712ceef]{float:right}.edit-actions[data-v-f712ceef]{justify-content:flex-end;gap:8px;display:flex}.skill-group[data-v-f712ceef]{margin-bottom:4px}.group-header[data-v-f712ceef]{cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:4px;align-items:center;gap:8px;padding:8px 4px;display:flex}.group-header[data-v-f712ceef]:hover{background:#00000008}.fold-arrow[data-v-f712ceef]{color:#999;flex-shrink:0;font-size:10px;transition:transform .2s}.fold-arrow.open[data-v-f712ceef]{transform:rotate(90deg)}.group-label[data-v-f712ceef]{color:inherit;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:13px;font-weight:600;overflow:hidden}.group-count[data-v-f712ceef]{color:#999;flex-shrink:0;font-size:12px}.group-update-btn[data-v-f712ceef]{flex-shrink:0}.group-body[data-v-f712ceef]{padding-left:4px}.source-info[data-v-f712ceef]{margin-bottom:4px}.source-row[data-v-f712ceef]{align-items:center;gap:10px;margin-bottom:6px;font-size:13px;display:flex}.source-label[data-v-f712ceef]{color:#888;flex-shrink:0;width:70px}.source-value[data-v-f712ceef]{word-break:break-all}.local-tag[data-v-f712ceef]{color:#2e7d32;background:#e8f5e9;border-radius:3px;padding:1px 8px;font-size:12px;display:inline-block}.path-text[data-v-f712ceef]{color:#666;font-family:monospace;font-size:12px}.source-actions[data-v-f712ceef]{gap:8px;margin-top:8px;display:flex}.local-hint[data-v-f712ceef]{color:#999;background:#00000005;border-radius:4px;margin-top:8px;padding:8px;font-size:12px;line-height:1.5}.siblings-body[data-v-f712ceef]{min-height:60px}.siblings-desc[data-v-f712ceef]{margin-bottom:12px;font-size:13px;line-height:1.6}.siblings-list[data-v-f712ceef]{flex-direction:column;gap:8px;margin-bottom:16px;display:flex}.siblings-actions[data-v-f712ceef]{justify-content:flex-end;gap:8px;display:flex}.batch-modal-body[data-v-f712ceef]{min-height:60px}.batch-desc[data-v-f712ceef]{margin-bottom:16px;font-size:13px;line-height:1.6}.batch-actions[data-v-f712ceef]{justify-content:flex-end;gap:8px;display:flex}.batch-executing[data-v-f712ceef]{color:#666;justify-content:center;align-items:center;gap:12px;padding:24px 0;font-size:13px;display:flex}.batch-result[data-v-f712ceef]{margin-bottom:16px}.batch-result-line[data-v-f712ceef]{flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:10px;font-size:13px;display:flex}.batch-result-label[data-v-f712ceef]{color:#888;flex-shrink:0}.page-header[data-v-1736a530]{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.page-header h2[data-v-1736a530]{font-size:20px;font-weight:600}.scene-grid[data-v-1736a530]{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;margin:2px;display:grid}.scene-card[data-v-1736a530]{transition:box-shadow .2s}.scene-card.active[data-v-1736a530]{box-shadow:0 0 0 2px #2080f0}.scene-desc[data-v-1736a530]{color:#666;margin:0;font-size:13px}.scene-footer[data-v-1736a530]{justify-content:space-between;align-items:center;display:flex}.hint-text[data-v-1736a530]{color:#999;font-size:12px}.page-header[data-v-5f659620]{margin-bottom:20px}.page-header h2[data-v-5f659620]{font-size:20px;font-weight:600}.section[data-v-5f659620]{margin-bottom:20px}.init-alert[data-v-5f659620]{margin-bottom:12px}.missing-list[data-v-5f659620]{flex-direction:column;gap:4px;display:flex}.missing-item[data-v-5f659620]{font-size:13px;line-height:1.6}.missing-item code[data-v-5f659620]{background:#0000000f;border-radius:3px;padding:1px 6px;font-size:12px}.skill-tag[data-v-5f659620]{margin:1px 2px;display:inline-block}.missing-hint[data-v-5f659620]{opacity:.7;margin-top:4px;font-size:12px}.source-status[data-v-5f659620]{margin-bottom:16px}.source-actions[data-v-5f659620]{flex-direction:column;gap:12px;display:flex}.action-buttons[data-v-5f659620]{gap:8px;display:flex}.healthy-text[data-v-5f659620]{color:#18a058;font-size:13px}.issue-text[data-v-5f659620]{color:#d03050;font-size:13px}.readme-dialog-desc[data-v-5f659620]{color:#555;margin-bottom:16px;font-size:14px}.readme-checkbox[data-v-5f659620]{align-items:flex-start;margin-bottom:12px;display:flex}.readme-checkbox-content[data-v-5f659620]{flex-direction:column;gap:2px;display:flex}.readme-checkbox-title[data-v-5f659620]{font-size:14px;font-weight:500}.readme-checkbox-desc[data-v-5f659620]{color:#999;font-size:12px}.page-header[data-v-97d38fe1]{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.page-header h2[data-v-97d38fe1]{font-size:20px;font-weight:600}.fade-enter-active[data-v-97d38fe1],.fade-leave-active[data-v-97d38fe1]{transition:opacity .2s}.fade-enter-from[data-v-97d38fe1],.fade-leave-to[data-v-97d38fe1]{opacity:0}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>mdk-skills 管理面板</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-Bq3Or_XK.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dgq5aj-Z.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="app"></div>
|
package/scripts/web-ui/server.js
CHANGED
|
@@ -169,22 +169,58 @@ function writeSkillMeta(dest, wasUpdated) {
|
|
|
169
169
|
|
|
170
170
|
// ---------- 异步 npx 管理:支持取消正在执行的进程 ----------
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
const runningTasks = new Map();
|
|
173
173
|
|
|
174
|
-
function
|
|
174
|
+
function runAsync(cmd, options = {}) {
|
|
175
|
+
const { cwd, timeout = 120000, taskId = "default" } = options;
|
|
175
176
|
return new Promise((resolve, reject) => {
|
|
176
|
-
|
|
177
|
-
|
|
177
|
+
// 同名任务已存在则先取消
|
|
178
|
+
if (runningTasks.has(taskId)) {
|
|
179
|
+
const old = runningTasks.get(taskId);
|
|
180
|
+
old.kill();
|
|
181
|
+
runningTasks.delete(taskId);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const proc = exec(cmd, { cwd, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
runningTasks.delete(taskId);
|
|
178
187
|
if (err) {
|
|
179
|
-
|
|
188
|
+
const e = new Error(err.killed ? "已取消" : (stderr || err.message));
|
|
189
|
+
e.stdout = stdout || "";
|
|
190
|
+
e.stderr = stderr || "";
|
|
191
|
+
e.killed = err.killed;
|
|
192
|
+
reject(e);
|
|
180
193
|
} else {
|
|
181
|
-
resolve();
|
|
194
|
+
resolve({ stdout: stdout || "", stderr: stderr || "" });
|
|
182
195
|
}
|
|
183
196
|
});
|
|
184
|
-
|
|
197
|
+
|
|
198
|
+
const timer = setTimeout(() => {
|
|
199
|
+
proc.kill();
|
|
200
|
+
runningTasks.delete(taskId);
|
|
201
|
+
const e = new Error("操作超时");
|
|
202
|
+
e.stdout = ""; e.stderr = ""; e.killed = true;
|
|
203
|
+
reject(e);
|
|
204
|
+
}, timeout);
|
|
205
|
+
|
|
206
|
+
proc.on("error", () => { clearTimeout(timer); runningTasks.delete(taskId); });
|
|
207
|
+
runningTasks.set(taskId, proc);
|
|
185
208
|
});
|
|
186
209
|
}
|
|
187
210
|
|
|
211
|
+
function cancelTask(taskId) {
|
|
212
|
+
if (taskId) {
|
|
213
|
+
const proc = runningTasks.get(taskId);
|
|
214
|
+
if (proc) { proc.kill(); runningTasks.delete(taskId); }
|
|
215
|
+
} else {
|
|
216
|
+
// 不传 taskId 取消全部
|
|
217
|
+
for (const [id, proc] of runningTasks) {
|
|
218
|
+
proc.kill();
|
|
219
|
+
runningTasks.delete(id);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
188
224
|
// 读取 profiles.json
|
|
189
225
|
function loadProfiles() {
|
|
190
226
|
const profilesPath = path.join(skillsSource, ".claude", "profiles.json");
|
|
@@ -410,12 +446,12 @@ async function handleApi(req, res) {
|
|
|
410
446
|
const tmpDir = path.join(os.tmpdir(), "mdk-pull-" + Date.now());
|
|
411
447
|
fs.mkdirSync(path.join(tmpDir, ".claude", "skills"), { recursive: true });
|
|
412
448
|
try {
|
|
413
|
-
await
|
|
449
|
+
await runAsync("npx --yes skills add \"" + url + "\" --copy -y -a claude-code", { cwd: tmpDir, taskId: "npx-pull" });
|
|
414
450
|
} catch (e) {
|
|
415
451
|
cleanNpxTemp();
|
|
416
452
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
417
|
-
if (e.
|
|
418
|
-
return sendJSON(res, { error: "
|
|
453
|
+
if (e.killed) return sendJSON(res, { cancelled: true }, 499);
|
|
454
|
+
return sendJSON(res, { error: "拉取失败:" + (e.stderr || e.message) }, 400);
|
|
419
455
|
}
|
|
420
456
|
cleanNpxTemp();
|
|
421
457
|
const imported = [];
|
|
@@ -472,12 +508,12 @@ async function handleApi(req, res) {
|
|
|
472
508
|
const tmpDir = path.join(os.tmpdir(), "mdk-update-" + Date.now());
|
|
473
509
|
fs.mkdirSync(path.join(tmpDir, ".claude", "skills"), { recursive: true });
|
|
474
510
|
try {
|
|
475
|
-
await
|
|
511
|
+
await runAsync("npx --yes skills add \"" + source.url + "\" --copy -y -a claude-code", { cwd: tmpDir, taskId: "npx-update-" + name });
|
|
476
512
|
} catch (e) {
|
|
477
513
|
cleanNpxTemp();
|
|
478
514
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
479
|
-
if (e.
|
|
480
|
-
return sendJSON(res, { error: "
|
|
515
|
+
if (e.killed) return sendJSON(res, { cancelled: true }, 499);
|
|
516
|
+
return sendJSON(res, { error: "重新拉取失败:" + (e.stderr || e.message) }, 400);
|
|
481
517
|
}
|
|
482
518
|
|
|
483
519
|
cleanNpxTemp();
|
|
@@ -533,12 +569,12 @@ async function handleApi(req, res) {
|
|
|
533
569
|
const tmpDir = path.join(os.tmpdir(), "mdk-batch-" + Date.now());
|
|
534
570
|
fs.mkdirSync(path.join(tmpDir, ".claude", "skills"), { recursive: true });
|
|
535
571
|
try {
|
|
536
|
-
await
|
|
572
|
+
await runAsync("npx --yes skills add \"" + url + "\" --copy -y -a claude-code", { cwd: tmpDir, taskId: "npx-batch" });
|
|
537
573
|
} catch (e) {
|
|
538
574
|
cleanNpxTemp();
|
|
539
575
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
540
|
-
if (e.
|
|
541
|
-
return sendJSON(res, { error: "
|
|
576
|
+
if (e.killed) return sendJSON(res, { cancelled: true }, 499);
|
|
577
|
+
return sendJSON(res, { error: "拉取失败:" + (e.stderr || e.message) }, 400);
|
|
542
578
|
}
|
|
543
579
|
|
|
544
580
|
cleanNpxTemp();
|
|
@@ -1159,10 +1195,8 @@ ${skillsList}
|
|
|
1159
1195
|
|
|
1160
1196
|
// POST /api/tasks/cancel — 取消正在执行的 npx 操作
|
|
1161
1197
|
if (method === "POST" && pathname === "/api/tasks/cancel") {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
_npxProcess = null;
|
|
1165
|
-
}
|
|
1198
|
+
const body = await parseBody(req);
|
|
1199
|
+
cancelTask(body.taskId);
|
|
1166
1200
|
return sendJSON(res, { ok: true });
|
|
1167
1201
|
}
|
|
1168
1202
|
|
|
@@ -243,6 +243,57 @@
|
|
|
243
243
|
</div>
|
|
244
244
|
</div>
|
|
245
245
|
</n-modal>
|
|
246
|
+
|
|
247
|
+
<!-- 全部更新弹窗 -->
|
|
248
|
+
<n-modal
|
|
249
|
+
v-model:show="showBatchModal"
|
|
250
|
+
:title="batchPhase === 'confirm' ? '批量更新确认' : batchPhase === 'executing' ? '正在更新...' : batchPhase === 'done' ? '更新完成' : '更新失败'"
|
|
251
|
+
preset="card"
|
|
252
|
+
style="width: 480px"
|
|
253
|
+
:mask-closable="batchPhase !== 'executing'"
|
|
254
|
+
@update:show="(v) => { if (!v && batchPhase === 'executing') cancelTask(); }"
|
|
255
|
+
>
|
|
256
|
+
<div class="batch-modal-body">
|
|
257
|
+
<template v-if="batchPhase === 'confirm'">
|
|
258
|
+
<p class="batch-desc">确定更新 "{{ batchGroup?.url }}" 下的 {{ batchGroup?.skills?.length }} 个技能吗?</p>
|
|
259
|
+
<div class="batch-actions">
|
|
260
|
+
<n-button size="small" @click="showBatchModal = false">取消</n-button>
|
|
261
|
+
<n-button size="small" type="primary" @click="doBatchUpdate">开始更新</n-button>
|
|
262
|
+
</div>
|
|
263
|
+
</template>
|
|
264
|
+
<template v-if="batchPhase === 'executing'">
|
|
265
|
+
<div class="batch-executing">
|
|
266
|
+
<n-spin size="small" />
|
|
267
|
+
<span>正在更新,请稍候...</span>
|
|
268
|
+
</div>
|
|
269
|
+
</template>
|
|
270
|
+
<template v-if="batchPhase === 'done'">
|
|
271
|
+
<div class="batch-result" v-if="batchResult">
|
|
272
|
+
<div v-if="batchResult.updated?.length > 0" class="batch-result-line">
|
|
273
|
+
<span class="batch-result-label">已更新:</span>
|
|
274
|
+
<n-tag v-for="name in batchResult.updated" :key="name" size="small" type="success">{{ name }}</n-tag>
|
|
275
|
+
</div>
|
|
276
|
+
<div v-if="batchResult.unchanged?.length > 0" class="batch-result-line">
|
|
277
|
+
<span class="batch-result-label">已是最新:</span>
|
|
278
|
+
<n-tag v-for="name in batchResult.unchanged" :key="name" size="small">{{ name }}</n-tag>
|
|
279
|
+
</div>
|
|
280
|
+
<div v-if="batchResult.notFound?.length > 0" class="batch-result-line">
|
|
281
|
+
<span class="batch-result-label">未找到:</span>
|
|
282
|
+
<n-tag v-for="name in batchResult.notFound" :key="name" size="small" type="warning">{{ name }}</n-tag>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="batch-actions">
|
|
286
|
+
<n-button size="small" type="primary" @click="showBatchModal = false">完成</n-button>
|
|
287
|
+
</div>
|
|
288
|
+
</template>
|
|
289
|
+
<template v-if="batchPhase === 'error'">
|
|
290
|
+
<n-alert type="error" :bordered="false">{{ batchError }}</n-alert>
|
|
291
|
+
<div class="batch-actions" style="margin-top: 12px;">
|
|
292
|
+
<n-button size="small" type="primary" @click="showBatchModal = false">关闭</n-button>
|
|
293
|
+
</div>
|
|
294
|
+
</template>
|
|
295
|
+
</div>
|
|
296
|
+
</n-modal>
|
|
246
297
|
</div>
|
|
247
298
|
</template>
|
|
248
299
|
|
|
@@ -318,6 +369,13 @@ const updatedSiblings = ref(null);
|
|
|
318
369
|
const siblingCheck = ref({});
|
|
319
370
|
const updatingSiblings = ref(false);
|
|
320
371
|
|
|
372
|
+
// 全部更新弹窗
|
|
373
|
+
const showBatchModal = ref(false);
|
|
374
|
+
const batchPhase = ref("confirm");
|
|
375
|
+
const batchGroup = ref(null);
|
|
376
|
+
const batchResult = ref(null);
|
|
377
|
+
const batchError = ref("");
|
|
378
|
+
|
|
321
379
|
async function handleSiblingUpdate() {
|
|
322
380
|
const selected = Object.keys(siblingCheck.value).filter((k) => siblingCheck.value[k]);
|
|
323
381
|
if (selected.length === 0) {
|
|
@@ -360,10 +418,12 @@ const installSelected = ref({});
|
|
|
360
418
|
const installing = ref(false);
|
|
361
419
|
|
|
362
420
|
function openPullModal() {
|
|
421
|
+
const savedY = window.scrollY;
|
|
363
422
|
showPullModal.value = true;
|
|
364
423
|
pullUrl.value = "";
|
|
365
424
|
pullResult.value = null;
|
|
366
425
|
pullError.value = "";
|
|
426
|
+
nextTick(() => window.scrollTo(0, savedY));
|
|
367
427
|
}
|
|
368
428
|
|
|
369
429
|
async function handlePull() {
|
|
@@ -512,6 +572,7 @@ async function loadReadme() {
|
|
|
512
572
|
}
|
|
513
573
|
|
|
514
574
|
async function showSkillDetail(skill) {
|
|
575
|
+
const savedY = window.scrollY;
|
|
515
576
|
detailSkill.value = skill;
|
|
516
577
|
detailVisible.value = true;
|
|
517
578
|
detailLoading.value = true;
|
|
@@ -521,6 +582,7 @@ async function showSkillDetail(skill) {
|
|
|
521
582
|
editVersion.value = skill.version || "1.0.0";
|
|
522
583
|
editDescription.value = skill.description || "";
|
|
523
584
|
editTags.value = [...(skill.tags || [])];
|
|
585
|
+
nextTick(() => window.scrollTo(0, savedY));
|
|
524
586
|
// 查来源
|
|
525
587
|
try {
|
|
526
588
|
const res = await getSkillSource(skill.name);
|
|
@@ -578,25 +640,31 @@ async function handleUpdate() {
|
|
|
578
640
|
}
|
|
579
641
|
|
|
580
642
|
async function batchUpdateGroup(group) {
|
|
581
|
-
const
|
|
582
|
-
|
|
643
|
+
const savedY = window.scrollY;
|
|
644
|
+
batchGroup.value = group;
|
|
645
|
+
batchResult.value = null;
|
|
646
|
+
batchError.value = "";
|
|
647
|
+
batchPhase.value = "confirm";
|
|
648
|
+
showBatchModal.value = true;
|
|
649
|
+
nextTick(() => window.scrollTo(0, savedY));
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
async function doBatchUpdate() {
|
|
653
|
+
batchPhase.value = "executing";
|
|
583
654
|
try {
|
|
584
|
-
const names =
|
|
585
|
-
const res = await batchUpdateSkills(names,
|
|
655
|
+
const names = batchGroup.value.skills.map((s) => s.name);
|
|
656
|
+
const res = await batchUpdateSkills(names, batchGroup.value.url);
|
|
586
657
|
if (res.ok) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
message.info(`${res.unchanged.length} 个技能已是最新,跳过`);
|
|
590
|
-
}
|
|
591
|
-
if (res.notFound && res.notFound.length > 0) {
|
|
592
|
-
message.warning(`${res.notFound.length} 个技能未找到,已跳过`);
|
|
593
|
-
}
|
|
658
|
+
batchResult.value = { updated: res.updated, unchanged: res.unchanged, notFound: res.notFound };
|
|
659
|
+
batchPhase.value = "done";
|
|
594
660
|
await loadSkills();
|
|
595
661
|
} else {
|
|
596
|
-
|
|
662
|
+
batchError.value = res.error || "批量更新失败";
|
|
663
|
+
batchPhase.value = "error";
|
|
597
664
|
}
|
|
598
665
|
} catch {
|
|
599
|
-
|
|
666
|
+
batchError.value = "批量更新失败";
|
|
667
|
+
batchPhase.value = "error";
|
|
600
668
|
}
|
|
601
669
|
}
|
|
602
670
|
|
|
@@ -667,6 +735,10 @@ onUnmounted(() => document.removeEventListener("visibilitychange", onFocus));
|
|
|
667
735
|
</script>
|
|
668
736
|
|
|
669
737
|
<style scoped>
|
|
738
|
+
.dashboard {
|
|
739
|
+
overflow-anchor: auto;
|
|
740
|
+
}
|
|
741
|
+
|
|
670
742
|
.page-header {
|
|
671
743
|
display: flex;
|
|
672
744
|
align-items: center;
|
|
@@ -937,4 +1009,49 @@ onUnmounted(() => document.removeEventListener("visibilitychange", onFocus));
|
|
|
937
1009
|
justify-content: flex-end;
|
|
938
1010
|
gap: 8px;
|
|
939
1011
|
}
|
|
1012
|
+
|
|
1013
|
+
/* 全部更新弹窗 */
|
|
1014
|
+
.batch-modal-body {
|
|
1015
|
+
min-height: 60px;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.batch-desc {
|
|
1019
|
+
font-size: 13px;
|
|
1020
|
+
line-height: 1.6;
|
|
1021
|
+
margin-bottom: 16px;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.batch-actions {
|
|
1025
|
+
display: flex;
|
|
1026
|
+
justify-content: flex-end;
|
|
1027
|
+
gap: 8px;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
.batch-executing {
|
|
1031
|
+
display: flex;
|
|
1032
|
+
align-items: center;
|
|
1033
|
+
gap: 12px;
|
|
1034
|
+
padding: 24px 0;
|
|
1035
|
+
justify-content: center;
|
|
1036
|
+
color: #666;
|
|
1037
|
+
font-size: 13px;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
.batch-result {
|
|
1041
|
+
margin-bottom: 16px;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.batch-result-line {
|
|
1045
|
+
display: flex;
|
|
1046
|
+
align-items: center;
|
|
1047
|
+
flex-wrap: wrap;
|
|
1048
|
+
gap: 6px;
|
|
1049
|
+
margin-bottom: 10px;
|
|
1050
|
+
font-size: 13px;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.batch-result-label {
|
|
1054
|
+
color: #888;
|
|
1055
|
+
flex-shrink: 0;
|
|
1056
|
+
}
|
|
940
1057
|
</style>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.status-bar[data-v-bc9519f9]{background:#fff;border-bottom:1px solid #e5e7eb;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 24px;display:flex}.status-item[data-v-bc9519f9]{color:#555;align-items:center;gap:6px;font-size:13px;display:flex}.status-item.clickable[data-v-bc9519f9]{cursor:pointer}.status-item.clickable[data-v-bc9519f9]:hover{color:#2080f0}.status-divider[data-v-bc9519f9]{background:#e0e0e0;width:1px;height:20px}[data-theme=dark] .status-bar{background:#1a1a2e;border-bottom-color:#333}[data-theme=dark] .status-item{color:#aaa}[data-theme=dark] .status-divider{background:#333}*{box-sizing:border-box;margin:0;padding:0}html,body,#app{background:#f5f7fa;height:100%}body{overflow-y:auto}*{scrollbar-width:none;-ms-overflow-style:none}::-webkit-scrollbar{display:none}.app-layout{flex-direction:column;min-height:100vh;padding-top:56px;display:flex}.app-header{z-index:100;background:#fff;border-bottom:1px solid #e5e7eb;align-items:center;height:56px;padding:0 24px;display:flex;position:fixed;top:0;left:0;right:0}.header-inner{justify-content:space-between;align-items:center;width:100%;display:flex}.header-left{align-items:center;gap:32px;display:flex}.logo{color:#1a1a1a;white-space:nowrap;font-size:18px;font-weight:700}.app-content{flex:1;width:100%;max-width:1000px;margin:0 auto;padding:24px}.markdown-content{color:#333;word-wrap:break-word;font-size:14px;line-height:1.7}.markdown-content h1{border-bottom:1px solid #eee;margin:20px 0 12px;padding-bottom:8px;font-size:22px;font-weight:700}.markdown-content h2{border-bottom:1px solid #eee;margin:18px 0 10px;padding-bottom:6px;font-size:18px;font-weight:700}.markdown-content h3{margin:16px 0 8px;font-size:16px;font-weight:600}.markdown-content h4{margin:14px 0 6px;font-size:14px;font-weight:600}.markdown-content h5,.markdown-content h6{margin:12px 0 6px;font-size:13px;font-weight:600}.markdown-content p{margin:8px 0}.markdown-content ul,.markdown-content ol{margin:8px 0;padding-left:24px}.markdown-content li{margin:4px 0}.markdown-content blockquote{color:#555;background:#f0f7ff;border-left:4px solid #2080f0;margin:10px 0;padding:8px 16px}.markdown-content blockquote p{margin:4px 0}.markdown-content a{color:#2080f0;text-decoration:none}.markdown-content a:hover{text-decoration:underline}.markdown-content hr{border:none;border-top:1px solid #e0e0e0;margin:16px 0}.markdown-content table{border-collapse:collapse;width:100%;margin:12px 0;font-size:13px}.markdown-content th,.markdown-content td{text-align:left;border:1px solid #e0e0e0;padding:8px 12px}.markdown-content th{background:#f5f7fa;font-weight:600}.markdown-content tr:nth-child(2n) td{background:#fafafa}.markdown-content img{border-radius:4px;max-width:100%;margin:8px 0}.markdown-content code{color:#d63384;background:#f0f0f0;border-radius:3px;padding:2px 6px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:13px}.markdown-content pre{border:1px solid #e8e8e8;border-radius:6px;margin:12px 0;padding:0;position:relative;overflow:hidden}.markdown-content pre code{color:#333;tab-size:2;background:#f8f9fa;padding:14px 16px;font-size:13px;line-height:1.5;display:block;overflow-x:auto}.markdown-content pre .copy-btn{color:#999;cursor:pointer;opacity:0;background:#fff;border:1px solid #e0e0e0;border-radius:4px;padding:3px 8px;font-size:11px;transition:opacity .2s;position:absolute;top:6px;right:6px}.readme-fold{border:1px solid #e5e7eb;border-radius:6px;margin-bottom:20px;overflow:hidden}.fold-header{cursor:pointer;-webkit-user-select:none;user-select:none;background:#fafafa;align-items:center;gap:6px;padding:10px 16px;font-size:14px;font-weight:600;display:flex}.fold-header:hover{background:#f0f0f0}.fold-arrow{color:#999;font-size:11px;transition:transform .2s}.fold-arrow.open{transform:rotate(90deg)}.fold-body{padding:0 16px 16px}.markdown-content pre:hover .copy-btn{opacity:1}.markdown-content pre .copy-btn:hover{color:#2080f0;border-color:#2080f0}.header-right{align-items:center;gap:8px;display:flex}[data-theme=dark] html,[data-theme=dark] body,[data-theme=dark] #app{background:#1a1a2e}[data-theme=dark] .app-header{background:#1a1a2e;border-bottom-color:#333}[data-theme=dark] .app-content{background:0 0}[data-theme=dark] .readme-fold{border-color:#333}[data-theme=dark] .fold-header{color:#e0e0e0;background:#252538}[data-theme=dark] .fold-header:hover{background:#2a2a40}[data-theme=dark] .fold-body{background:#1e1e32}[data-theme=dark] .fold-arrow{color:#888}[data-theme=dark] .markdown-content{color:#ccc}[data-theme=dark] .markdown-content h1,[data-theme=dark] .markdown-content h2{color:#eee;border-bottom-color:#333}[data-theme=dark] .markdown-content h3,[data-theme=dark] .markdown-content h4{color:#eee}[data-theme=dark] .markdown-content code{color:#e06c9f;background:#2a2a40}[data-theme=dark] .markdown-content pre{border-color:#333}[data-theme=dark] .markdown-content pre code{color:#d4d4d4;background:#1e1e2e}[data-theme=dark] .markdown-content blockquote{color:#bbb;background:#252538;border-left-color:#4a6cf7}[data-theme=dark] .markdown-content a{color:#6a8cff}[data-theme=dark] .markdown-content th{background:#252538}[data-theme=dark] .markdown-content td{border-color:#333}[data-theme=dark] .markdown-content tr:nth-child(2n) td{background:#222238}[data-theme=dark] .markdown-content hr{border-top-color:#333}[data-theme=dark] .markdown-content img{filter:brightness(.85)}[data-theme=dark] .page-header h2{color:#e0e0e0}[data-theme=dark] .scene-desc{color:#aaa}.fade-enter-active,.fade-leave-active{transition:opacity .9s,transform .9s}.fade-enter-from{opacity:0;transform:translateY(6px)}.fade-leave-to{opacity:0}.skill-card[data-v-f2c0de50]{cursor:pointer;margin-bottom:12px;transition:box-shadow .2s}.skill-card[data-v-f2c0de50]:hover{box-shadow:0 2px 8px #00000014}.skill-meta[data-v-f2c0de50]{align-items:center;gap:8px;margin-bottom:8px;display:flex}.skill-version[data-v-f2c0de50]{color:#888;font-family:monospace;font-size:12px}.skill-desc[data-v-f2c0de50]{color:#666;text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:13px;overflow:hidden}.page-header[data-v-b6b1cdad]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;margin-bottom:4px;display:flex}.page-header h2[data-v-b6b1cdad]{font-size:20px;font-weight:600}.header-actions[data-v-b6b1cdad]{align-items:center;gap:8px;display:flex}.tag-filter[data-v-b6b1cdad]{flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:16px;display:flex}.detail-status[data-v-b6b1cdad]{justify-content:center;padding:40px 0;display:flex}.detail-body[data-v-b6b1cdad]{max-height:65vh;padding:16px 24px;overflow-y:auto}.edit-panel[data-v-b6b1cdad]{margin-bottom:4px}.edit-row[data-v-b6b1cdad]{align-items:flex-start;gap:10px;margin-bottom:10px;display:flex}.edit-label[data-v-b6b1cdad]{color:#888;flex-shrink:0;width:50px;font-size:13px;line-height:30px}.update-count-hint[data-v-b6b1cdad]{color:#e68a00;margin-left:8px;font-family:monospace;font-size:12px}.pull-modal-body[data-v-b6b1cdad]{min-height:100px}.pull-section[data-v-b6b1cdad]{margin-top:12px}.pull-input-row[data-v-b6b1cdad]{gap:8px;margin-bottom:8px;display:flex}.pull-input-row .n-input[data-v-b6b1cdad]{flex:1}.pull-error[data-v-b6b1cdad]{margin-bottom:8px}.pull-result[data-v-b6b1cdad]{margin-top:8px}.pull-result-line[data-v-b6b1cdad]{flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:8px;font-size:13px;display:flex}.pull-result-label[data-v-b6b1cdad]{color:#888;flex-shrink:0}.pull-result-hint[data-v-b6b1cdad]{color:#999;font-size:12px}.install-panel[data-v-b6b1cdad]{background:#00000005;border-radius:6px;margin-top:12px;padding:12px}.install-panel-label[data-v-b6b1cdad]{color:#666;margin-bottom:8px;font-size:13px}.install-check-list[data-v-b6b1cdad]{margin-bottom:10px}.install-btn[data-v-b6b1cdad]{float:right}.edit-actions[data-v-b6b1cdad]{justify-content:flex-end;gap:8px;display:flex}.skill-group[data-v-b6b1cdad]{margin-bottom:4px}.group-header[data-v-b6b1cdad]{cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:4px;align-items:center;gap:8px;padding:8px 4px;display:flex}.group-header[data-v-b6b1cdad]:hover{background:#00000008}.fold-arrow[data-v-b6b1cdad]{color:#999;flex-shrink:0;font-size:10px;transition:transform .2s}.fold-arrow.open[data-v-b6b1cdad]{transform:rotate(90deg)}.group-label[data-v-b6b1cdad]{color:inherit;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:13px;font-weight:600;overflow:hidden}.group-count[data-v-b6b1cdad]{color:#999;flex-shrink:0;font-size:12px}.group-update-btn[data-v-b6b1cdad]{flex-shrink:0}.group-body[data-v-b6b1cdad]{padding-left:4px}.source-info[data-v-b6b1cdad]{margin-bottom:4px}.source-row[data-v-b6b1cdad]{align-items:center;gap:10px;margin-bottom:6px;font-size:13px;display:flex}.source-label[data-v-b6b1cdad]{color:#888;flex-shrink:0;width:70px}.source-value[data-v-b6b1cdad]{word-break:break-all}.local-tag[data-v-b6b1cdad]{color:#2e7d32;background:#e8f5e9;border-radius:3px;padding:1px 8px;font-size:12px;display:inline-block}.path-text[data-v-b6b1cdad]{color:#666;font-family:monospace;font-size:12px}.source-actions[data-v-b6b1cdad]{gap:8px;margin-top:8px;display:flex}.local-hint[data-v-b6b1cdad]{color:#999;background:#00000005;border-radius:4px;margin-top:8px;padding:8px;font-size:12px;line-height:1.5}.siblings-body[data-v-b6b1cdad]{min-height:60px}.siblings-desc[data-v-b6b1cdad]{margin-bottom:12px;font-size:13px;line-height:1.6}.siblings-list[data-v-b6b1cdad]{flex-direction:column;gap:8px;margin-bottom:16px;display:flex}.siblings-actions[data-v-b6b1cdad]{justify-content:flex-end;gap:8px;display:flex}.page-header[data-v-1736a530]{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.page-header h2[data-v-1736a530]{font-size:20px;font-weight:600}.scene-grid[data-v-1736a530]{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;margin:2px;display:grid}.scene-card[data-v-1736a530]{transition:box-shadow .2s}.scene-card.active[data-v-1736a530]{box-shadow:0 0 0 2px #2080f0}.scene-desc[data-v-1736a530]{color:#666;margin:0;font-size:13px}.scene-footer[data-v-1736a530]{justify-content:space-between;align-items:center;display:flex}.hint-text[data-v-1736a530]{color:#999;font-size:12px}.page-header[data-v-5f659620]{margin-bottom:20px}.page-header h2[data-v-5f659620]{font-size:20px;font-weight:600}.section[data-v-5f659620]{margin-bottom:20px}.init-alert[data-v-5f659620]{margin-bottom:12px}.missing-list[data-v-5f659620]{flex-direction:column;gap:4px;display:flex}.missing-item[data-v-5f659620]{font-size:13px;line-height:1.6}.missing-item code[data-v-5f659620]{background:#0000000f;border-radius:3px;padding:1px 6px;font-size:12px}.skill-tag[data-v-5f659620]{margin:1px 2px;display:inline-block}.missing-hint[data-v-5f659620]{opacity:.7;margin-top:4px;font-size:12px}.source-status[data-v-5f659620]{margin-bottom:16px}.source-actions[data-v-5f659620]{flex-direction:column;gap:12px;display:flex}.action-buttons[data-v-5f659620]{gap:8px;display:flex}.healthy-text[data-v-5f659620]{color:#18a058;font-size:13px}.issue-text[data-v-5f659620]{color:#d03050;font-size:13px}.readme-dialog-desc[data-v-5f659620]{color:#555;margin-bottom:16px;font-size:14px}.readme-checkbox[data-v-5f659620]{align-items:flex-start;margin-bottom:12px;display:flex}.readme-checkbox-content[data-v-5f659620]{flex-direction:column;gap:2px;display:flex}.readme-checkbox-title[data-v-5f659620]{font-size:14px;font-weight:500}.readme-checkbox-desc[data-v-5f659620]{color:#999;font-size:12px}.page-header[data-v-97d38fe1]{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.page-header h2[data-v-97d38fe1]{font-size:20px;font-weight:600}.fade-enter-active[data-v-97d38fe1],.fade-leave-active[data-v-97d38fe1]{transition:opacity .2s}.fade-enter-from[data-v-97d38fe1],.fade-leave-to[data-v-97d38fe1]{opacity:0}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|