dsh-skill-hub 0.3.6 → 0.3.7
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/lib/client.js +890 -356
- package/lib/client.js.map +1 -1
- package/lib/index.js +401 -47
- package/lib/types/client/SkillHubSettingsCard.d.ts +0 -2
- package/lib/types/client/api.d.ts +5 -1
- package/lib/types/client/helpers.d.ts +10 -0
- package/lib/types/client/locales.d.ts +30 -0
- package/lib/types/client/panel/DisabledRow.d.ts +2 -0
- package/lib/types/client/panel/SkillDetailView.d.ts +5 -1
- package/lib/types/client/panel/dialogs.d.ts +19 -0
- package/lib/types/client/panel/useSkillHub.d.ts +12 -1
- package/lib/types/client/settings-card.d.ts +0 -17
- package/lib/types/client/settings-form.d.ts +0 -1
- package/lib/types/protocol.d.ts +40 -17
- package/lib/types/repo.d.ts +4 -6
- package/lib/types/skillfs.d.ts +13 -0
- package/package.json +29 -28
- package/src/client/SkillHubSettingsCard.tsx +0 -2
- package/src/client/api.ts +18 -0
- package/src/client/helpers.ts +40 -0
- package/src/client/locales.ts +60 -0
- package/src/client/panel/DisabledRow.tsx +22 -7
- package/src/client/panel/MarketView.tsx +8 -1
- package/src/client/panel/ScenesView.tsx +1 -1
- package/src/client/panel/SkillDetailView.tsx +35 -11
- package/src/client/panel/SkillHubPanel.tsx +42 -4
- package/src/client/panel/SkillRow.tsx +5 -2
- package/src/client/panel/SourcesView.tsx +2 -17
- package/src/client/panel/dialogs.tsx +61 -0
- package/src/client/panel/panel.module.css +1 -8
- package/src/client/panel/useSkillHub.ts +97 -12
- package/src/client/settings-card.tsx +0 -42
- package/src/client/settings-form.ts +1 -5
- package/src/protocol.ts +42 -8
- package/src/repo.ts +71 -29
- package/src/routes.test.ts +22 -0
- package/src/routes.ts +181 -10
- package/src/skillfs.ts +188 -3
package/lib/client.js
CHANGED
|
@@ -46,7 +46,9 @@ window.__ModuleLoader__.load({
|
|
|
46
46
|
sourceSync: "/api/skill-hub/sources/sync",
|
|
47
47
|
sourceDelete: "/api/skill-hub/sources/delete",
|
|
48
48
|
sourceRestore: "/api/skill-hub/sources/restore",
|
|
49
|
-
sourceTrashClear: "/api/skill-hub/sources/trash/clear"
|
|
49
|
+
sourceTrashClear: "/api/skill-hub/sources/trash/clear",
|
|
50
|
+
diagnosticFix: "/api/skill-hub/diagnostic/fix",
|
|
51
|
+
marketSourceVersions: "/api/skill-hub/market/source/versions"
|
|
50
52
|
};
|
|
51
53
|
/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */
|
|
52
54
|
function isProjectSource(source) {
|
|
@@ -177,6 +179,10 @@ window.__ModuleLoader__.load({
|
|
|
177
179
|
body: JSON.stringify({ repo })
|
|
178
180
|
}));
|
|
179
181
|
}
|
|
182
|
+
/** Releases + branches of a market source for the version picker. */
|
|
183
|
+
async marketSourceVersions(repo) {
|
|
184
|
+
return readJson(await fetchWithTimeout(SKILL_HUB_API.marketSourceVersions + "?repo=" + encodeURIComponent(repo)));
|
|
185
|
+
}
|
|
180
186
|
/** Pin a market source to an explicit ref (branch picker). */
|
|
181
187
|
async setMarketSourceRef(repo, ref) {
|
|
182
188
|
return readJson(await fetchWithTimeout(SKILL_HUB_API.marketSourceRef, {
|
|
@@ -338,6 +344,14 @@ window.__ModuleLoader__.load({
|
|
|
338
344
|
async clearTrash() {
|
|
339
345
|
return readJson(await fetchWithTimeout(SKILL_HUB_API.sourceTrashClear, { method: "POST" }));
|
|
340
346
|
}
|
|
347
|
+
/** Auto-fix a fixable diagnostic (e.g. unquoted colon). */
|
|
348
|
+
async fixDiagnostic(path) {
|
|
349
|
+
return readJson(await fetchWithTimeout(SKILL_HUB_API.diagnosticFix, {
|
|
350
|
+
method: "POST",
|
|
351
|
+
headers: { "content-type": "application/json" },
|
|
352
|
+
body: JSON.stringify({ path })
|
|
353
|
+
}));
|
|
354
|
+
}
|
|
341
355
|
};
|
|
342
356
|
//#endregion
|
|
343
357
|
//#region src/client/locales.ts
|
|
@@ -407,12 +421,22 @@ window.__ModuleLoader__.load({
|
|
|
407
421
|
"market.branchTitle": "选择分支",
|
|
408
422
|
"market.branchHint": "该仓库没有正式发布,选择要跟踪的分支(默认为 main):",
|
|
409
423
|
"market.branchConfirm": "确定",
|
|
424
|
+
"market.versionTitle": "切换跟踪版本",
|
|
425
|
+
"market.versionText": "选择 {repo} 要跟踪的版本,切换后建议重新扫描并同步已装技能",
|
|
426
|
+
"market.versionCurrent": "当前 {ref}",
|
|
427
|
+
"market.versionReleases": "发布版",
|
|
428
|
+
"market.versionBranches": "分支",
|
|
429
|
+
"market.versionCustom": "自定义(tag / 分支 / commit)",
|
|
430
|
+
"market.versionConfirm": "切换到 {ref}",
|
|
431
|
+
"market.versionHint": "点击切换跟踪版本",
|
|
432
|
+
"market.unpinned": "未定版",
|
|
410
433
|
"market.syncTitle": "同步本地技能",
|
|
411
434
|
"market.syncText": "市场源已对齐到 {ref},要同步更新以下本地技能吗?",
|
|
412
435
|
"market.syncNone": "该来源还没有导入本地技能。",
|
|
413
436
|
"market.syncCancel": "跳过",
|
|
414
437
|
"market.removeHint": "移除源不影响已安装的技能。",
|
|
415
438
|
"repo.ready": "发现 {count} 个可导入技能",
|
|
439
|
+
"repo.truncated": "⚠ 仓库过大,仅展示部分技能(GitHub 截断),可缩小仓库或指定子目录",
|
|
416
440
|
"repo.empty": "没有找到可导入技能。",
|
|
417
441
|
"repo.selectAll": "全选",
|
|
418
442
|
"repo.clearAll": "清空",
|
|
@@ -485,6 +509,26 @@ window.__ModuleLoader__.load({
|
|
|
485
509
|
"row.enable": "启用",
|
|
486
510
|
"row.delete": "移入回收站",
|
|
487
511
|
"row.open": "查看 {name} 详情(回车)",
|
|
512
|
+
"row.duplicate": "重名",
|
|
513
|
+
"row.duplicateHint": "同名技能存在多个来源,当前显示为优先级最高的版本",
|
|
514
|
+
"row.copy": "复制",
|
|
515
|
+
"row.copyMention": "复制 $mention",
|
|
516
|
+
"row.copied": "已复制",
|
|
517
|
+
"row.copyPath": "复制路径",
|
|
518
|
+
"detail.copyMention": "复制 $mention",
|
|
519
|
+
"detail.copyPath": "复制路径",
|
|
520
|
+
"detail.copied": "已复制",
|
|
521
|
+
"diag.fix": "修复",
|
|
522
|
+
"diag.fixing": "修复中…",
|
|
523
|
+
"diag.fixed": "已修复",
|
|
524
|
+
"diag.fixConfirm": "用自动修复重写以下文件的 frontmatter?建议先备份:{path}",
|
|
525
|
+
"filter.invocation": "调用",
|
|
526
|
+
"filter.invocationAll": "全部调用",
|
|
527
|
+
"filter.modelOnly": "模型可调",
|
|
528
|
+
"filter.userOnly": "用户可调",
|
|
529
|
+
"filter.showing": "显示 {shown}/{total}(已启用){filtered}",
|
|
530
|
+
"filter.filteredSuffix": " · 已筛选",
|
|
531
|
+
"filter.shortened": "短描述 {count} 条,悬浮看全文",
|
|
488
532
|
"delete.confirmTitle": "移入回收站?",
|
|
489
533
|
"delete.confirmText": "确定把「{name}」移入回收站吗?可随时恢复。",
|
|
490
534
|
"delete.confirm": "移入回收站",
|
|
@@ -632,12 +676,22 @@ window.__ModuleLoader__.load({
|
|
|
632
676
|
"market.branchTitle": "Choose a branch",
|
|
633
677
|
"market.branchHint": "This repo has no releases. Pick a branch to track (main by default):",
|
|
634
678
|
"market.branchConfirm": "Confirm",
|
|
679
|
+
"market.versionTitle": "Switch tracked version",
|
|
680
|
+
"market.versionText": "Pick the version for {repo} to track; rescan and sync installed skills afterwards",
|
|
681
|
+
"market.versionCurrent": "current {ref}",
|
|
682
|
+
"market.versionReleases": "Releases",
|
|
683
|
+
"market.versionBranches": "Branches",
|
|
684
|
+
"market.versionCustom": "Custom (tag / branch / commit)",
|
|
685
|
+
"market.versionConfirm": "Switch to {ref}",
|
|
686
|
+
"market.versionHint": "Click to switch the tracked version",
|
|
687
|
+
"market.unpinned": "unpinned",
|
|
635
688
|
"market.syncTitle": "Update local skills",
|
|
636
689
|
"market.syncText": "Market source aligned to {ref}. Update these local skills?",
|
|
637
690
|
"market.syncNone": "No local skills tracked from this repo yet.",
|
|
638
691
|
"market.syncCancel": "Skip",
|
|
639
692
|
"market.removeHint": "Removing a source does not affect installed skills.",
|
|
640
693
|
"repo.ready": "{count} importable skills found",
|
|
694
|
+
"repo.truncated": "⚠ Repo too large, only partial skills shown (GitHub truncated)",
|
|
641
695
|
"repo.empty": "No importable skills found.",
|
|
642
696
|
"repo.selectAll": "Select all",
|
|
643
697
|
"repo.clearAll": "Clear",
|
|
@@ -710,6 +764,26 @@ window.__ModuleLoader__.load({
|
|
|
710
764
|
"row.enable": "Enable",
|
|
711
765
|
"row.delete": "Move to trash",
|
|
712
766
|
"row.open": "View {name} details (Enter)",
|
|
767
|
+
"row.duplicate": "duplicate",
|
|
768
|
+
"row.duplicateHint": "Multiple sources provide this name; the highest-priority one is shown",
|
|
769
|
+
"row.copy": "Copy",
|
|
770
|
+
"row.copyMention": "Copy $mention",
|
|
771
|
+
"row.copied": "Copied",
|
|
772
|
+
"row.copyPath": "Copy path",
|
|
773
|
+
"detail.copyMention": "Copy $mention",
|
|
774
|
+
"detail.copyPath": "Copy path",
|
|
775
|
+
"detail.copied": "Copied",
|
|
776
|
+
"diag.fix": "Fix",
|
|
777
|
+
"diag.fixing": "Fixing…",
|
|
778
|
+
"diag.fixed": "Fixed",
|
|
779
|
+
"diag.fixConfirm": "Rewrite the frontmatter of this file with the auto-fix? Back it up first: {path}",
|
|
780
|
+
"filter.invocation": "Invocation",
|
|
781
|
+
"filter.invocationAll": "All",
|
|
782
|
+
"filter.modelOnly": "Model",
|
|
783
|
+
"filter.userOnly": "User",
|
|
784
|
+
"filter.showing": "Showing {shown}/{total} (enabled){filtered}",
|
|
785
|
+
"filter.filteredSuffix": " · filtered",
|
|
786
|
+
"filter.shortened": "{count} short descriptions, hover for full text",
|
|
713
787
|
"delete.confirmTitle": "Move to trash?",
|
|
714
788
|
"delete.confirmText": "Move \"{name}\" to trash? It can be restored anytime.",
|
|
715
789
|
"delete.confirm": "Move to trash",
|
|
@@ -951,6 +1025,40 @@ window.__ModuleLoader__.load({
|
|
|
951
1025
|
if (error instanceof Error) return error.message;
|
|
952
1026
|
return String(error);
|
|
953
1027
|
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Whether a displayName is worth showing beside the kebab-case name.
|
|
1030
|
+
* Pure case/punctuation variants (e.g. "Code Review" vs "code-review") are redundant.
|
|
1031
|
+
*/
|
|
1032
|
+
function isDisplayNameDistinct(name, displayName) {
|
|
1033
|
+
if (displayName === void 0) return false;
|
|
1034
|
+
const normalize = (s) => s.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff]+/g, "");
|
|
1035
|
+
return normalize(displayName) !== normalize(name);
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Copy text to the clipboard. Uses the async API with a positioned-textarea
|
|
1039
|
+
* fallback for insecure contexts. Resolves true only when the copy succeeded.
|
|
1040
|
+
*/
|
|
1041
|
+
async function copyTextToClipboard(text) {
|
|
1042
|
+
if (navigator.clipboard?.writeText !== void 0) try {
|
|
1043
|
+
await navigator.clipboard.writeText(text);
|
|
1044
|
+
return true;
|
|
1045
|
+
} catch {}
|
|
1046
|
+
try {
|
|
1047
|
+
const ta = document.createElement("textarea");
|
|
1048
|
+
ta.value = text;
|
|
1049
|
+
ta.setAttribute("readonly", "");
|
|
1050
|
+
ta.style.position = "fixed";
|
|
1051
|
+
ta.style.top = "0";
|
|
1052
|
+
ta.style.opacity = "0";
|
|
1053
|
+
document.body.appendChild(ta);
|
|
1054
|
+
ta.select();
|
|
1055
|
+
const ok = document.execCommand("copy");
|
|
1056
|
+
ta.remove();
|
|
1057
|
+
return ok;
|
|
1058
|
+
} catch {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
954
1062
|
//#endregion
|
|
955
1063
|
//#region src/client/panel/format.ts
|
|
956
1064
|
/** Model-invocable dot color default. Single source for the TS side; the
|
|
@@ -2405,7 +2513,7 @@ window.__ModuleLoader__.load({
|
|
|
2405
2513
|
}
|
|
2406
2514
|
async store(field, value) {
|
|
2407
2515
|
await this.scope.set(field, value);
|
|
2408
|
-
return this.
|
|
2516
|
+
return this.userRecord()?.[field] === value;
|
|
2409
2517
|
}
|
|
2410
2518
|
userRecord() {
|
|
2411
2519
|
const user = this.scope.getSnapshot().user;
|
|
@@ -2428,9 +2536,6 @@ window.__ModuleLoader__.load({
|
|
|
2428
2536
|
const base = this.scope.getSnapshot().base;
|
|
2429
2537
|
return typeof base === "object" && base !== null ? base[field] : void 0;
|
|
2430
2538
|
}
|
|
2431
|
-
userLayer() {
|
|
2432
|
-
return this.userRecord();
|
|
2433
|
-
}
|
|
2434
2539
|
stored(field) {
|
|
2435
2540
|
const user = this.userRecord();
|
|
2436
2541
|
return user !== void 0 && Object.hasOwn(user, field);
|
|
@@ -2658,7 +2763,7 @@ window.__ModuleLoader__.load({
|
|
|
2658
2763
|
}
|
|
2659
2764
|
//#endregion
|
|
2660
2765
|
//#region \0dsh-css:/Users/huanyi/Documents/personal/tools/dsh-skill-hub/src/client/panel/panel.module.css.mjs
|
|
2661
|
-
const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;color-scheme:light dark;--hub-model:#2f81f7;--hub-user:#3fb950;flex-direction:column;gap:14px;max-width:720px;margin:0 auto;padding:28px 20px 44px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Helvetica Neue,sans-serif;display:flex}._6VtqdG_header{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}._6VtqdG_title{letter-spacing:-.02em;margin:0;font-size:24px;font-weight:700}._6VtqdG_hint{opacity:.5;font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:#80808024;border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:inherit;opacity:.62;cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{opacity:.9}._6VtqdG_segBtnActive{opacity:1;background:#80808047;font-weight:600}._6VtqdG_search{width:100%;color:inherit;background:#8080801f;border:none;border-radius:10px;outline:none;padding:10px 14px;font-size:13px;transition:background .15s}._6VtqdG_search::placeholder{opacity:.45}._6VtqdG_search:focus{background:#8080802e}._6VtqdG_section{background:#8080800f;border-radius:12px;flex-direction:column;margin-top:4px;display:flex;overflow:hidden;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_sectionTitle{margin:14px 16px 2px;font-size:13px;font-weight:700}._6VtqdG_groupHead{box-sizing:border-box;align-items:center;gap:8px;min-height:44px;padding:10px 14px;display:flex}._6VtqdG_groupTitle{opacity:.92;flex:1;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:600;line-height:1;display:inline-flex}._6VtqdG_groupOps{flex-wrap:wrap;flex:none;align-items:center;gap:6px;display:inline-flex}._6VtqdG_opBtn{color:inherit;cursor:pointer;background:#80808021;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:#80808038}._6VtqdG_opBtn:disabled{opacity:.4;cursor:default}._6VtqdG_row{cursor:pointer;background:0 0;align-items:center;gap:12px;padding:10px 14px;transition:background .12s;display:flex}._6VtqdG_row:hover{background:#80808014}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-model);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid #80808021}._6VtqdG_rowMain{flex:1;min-width:0}._6VtqdG_rowName{align-items:center;gap:5px;font-size:13.5px;display:flex}._6VtqdG_rowNameText{font-weight:600}._6VtqdG_rowDesc{opacity:.52;white-space:nowrap;text-overflow:ellipsis;margin-top:1px;font-size:12.5px;overflow:hidden}._6VtqdG_rowMeta{opacity:.45;white-space:nowrap;flex:none;font-size:11.5px}._6VtqdG_badges{flex:none;align-items:center;gap:6px;display:flex}._6VtqdG_badge{opacity:.8;white-space:nowrap;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeModel{color:var(--hub-model);border-color:currentColor}._6VtqdG_badgeUser{color:var(--hub-user);border-color:currentColor}._6VtqdG_badgeUses{color:#d29922;border-color:currentColor}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{cursor:pointer;background:#8080804d;border:none;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:#34c759}._6VtqdG_switchThumb{background:#fff;border-radius:50%;width:17px;height:17px;transition:transform .18s;display:block;transform:translate(0);box-shadow:0 1px 2px #00000040}._6VtqdG_switchOn ._6VtqdG_switchThumb{transform:translate(15px)}._6VtqdG_empty{opacity:.5;text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{background:#d299220f;border-left:3px solid #d29922;padding:9px 14px;font-size:12px}._6VtqdG_diagPath{opacity:.75;word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{opacity:.65;margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:#d1242f;white-space:pre-wrap;word-break:break-all;background:#d1242f12;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_successBanner{color:#3fb950;white-space:pre-wrap;word-break:break-all;background:#3fb95014;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_detailHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}._6VtqdG_back{color:inherit;cursor:pointer;background:#8080801f;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:#80808033}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{opacity:.6;flex-direction:column;gap:4px;font-size:12px;display:flex}._6VtqdG_detailMetaLine{word-break:break-all}._6VtqdG_detailContent{white-space:pre-wrap;word-break:break-word;background:#8080800d;border-radius:12px;max-height:62vh;padding:14px 16px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.6;overflow:auto}._6VtqdG_form{background:#8080800d;border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_formRow{flex-direction:column;gap:5px;display:flex}._6VtqdG_formLabel{opacity:.6;font-size:12px}._6VtqdG_input,._6VtqdG_select{color:inherit;background:#8080801f;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:#8080802e}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;color:inherit;background:#8080801f;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:#80808033}._6VtqdG_primary{background:var(--hub-model);color:#fff}._6VtqdG_primary:hover{opacity:.92;background:#2f81f7}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{color:#fff;background:#d1242f}._6VtqdG_danger:hover{opacity:.92;background:#d1242f}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:#d1242f}._6VtqdG_formSuccess{color:#3fb950}._6VtqdG_muted{opacity:.55}._6VtqdG_dot{vertical-align:middle;border-radius:50%;width:7px;height:7px;margin-left:5px;display:inline-block}._6VtqdG_dotModel{background:var(--hub-model)}._6VtqdG_dotUser{background:var(--hub-user)}._6VtqdG_legend{opacity:.55;flex-wrap:wrap;align-items:center;gap:12px;padding:2px 2px 0;font-size:11.5px;display:flex}._6VtqdG_legendItem{align-items:center;gap:4px;display:inline-flex}._6VtqdG_legendItem ._6VtqdG_dot{margin-left:0}._6VtqdG_legendHint{opacity:.8}._6VtqdG_badgeSource,._6VtqdG_badgeCount{opacity:.72;background:#8080801a;border:none}._6VtqdG_badgeDisabled{opacity:.58;background:#8080801a;border:none}._6VtqdG_disclosure{min-width:0;color:inherit;cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:7px;min-height:24px;padding:2px 0;display:flex}._6VtqdG_disclosure:hover ._6VtqdG_groupTitle{opacity:1}._6VtqdG_chevron{opacity:.55;border-bottom:1.5px solid;border-right:1.5px solid;flex:none;align-self:center;width:8px;height:8px;margin-right:2px;transition:transform .15s;transform:rotate(45deg)translateY(-1px)}._6VtqdG_chevronCollapsed{transform:rotate(-45deg)translateY(-1px)}._6VtqdG_headerCount{opacity:.5;white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{opacity:.45;white-space:nowrap;font-variant-numeric:tabular-nums;margin-left:6px;font-size:12px;font-weight:500}._6VtqdG_subbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_legendToggle{width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;background:#80808024;border:none;border-radius:50%;flex:none;font-size:12px;line-height:1;transition:opacity .15s,background .15s}._6VtqdG_legendToggle:hover{opacity:1}._6VtqdG_legendToggleActive{opacity:1;background:#80808047}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:#d29922;vertical-align:1px;background:#d299221f;border-radius:999px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:700;line-height:1.6;display:inline-block}._6VtqdG_useTime{opacity:.45;white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773}._6VtqdG_switchMixed ._6VtqdG_switchThumb{transform:translate(7.5px);box-shadow:0 1px 2px #00000040}._6VtqdG_groupTitleInner{align-items:baseline;display:inline-flex}._6VtqdG_sourceLink{color:inherit;opacity:.9;border-bottom:1px dotted;font-weight:600;text-decoration:none}._6VtqdG_sourceLink:hover{opacity:1}._6VtqdG_statusBadges{flex:none;align-items:center;gap:4px;display:inline-flex}._6VtqdG_statusBadge{opacity:.8;white-space:nowrap;background:#8080801a;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:#3fb950;background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:#d29922;background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:#d1242f;background:#d1242f14;border-color:currentColor}._6VtqdG_statusWrap{cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;padding:0;font-family:inherit;display:inline-flex}._6VtqdG_statusWrap:hover ._6VtqdG_statusBadge{opacity:1}._6VtqdG_statusButton{cursor:pointer;font-family:inherit}._6VtqdG_statusButton:hover{opacity:1}._6VtqdG_opDanger{color:#d1242f;background:#d1242f1a}._6VtqdG_opDanger:hover{background:#d1242f2e}._6VtqdG_iconBtn{border-radius:999px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}._6VtqdG_sourceCard{background:#8080800d;border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;font-size:12px;display:flex}._6VtqdG_sourceCardTitle{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_dialogOverlay{z-index:50;-webkit-backdrop-filter:blur(2px);background:#00000059;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}._6VtqdG_dialog{background:var(--dsw-surface,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-text,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}@media (prefers-color-scheme:dark){._6VtqdG_dialog{color:#f5f5f7;background:#2c2c2e}}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{opacity:.65;margin:0 0 10px;font-size:12.5px;line-height:1.5}._6VtqdG_dialogList{flex-direction:column;gap:5px;max-height:200px;margin:0 0 14px;padding:0;list-style:none;display:flex;overflow:auto}._6VtqdG_dialogList li{opacity:.85;word-break:break-all;font-size:12.5px}._6VtqdG_dialogActions{justify-content:flex-end;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_search{flex:1;min-width:160px}._6VtqdG_filterBar ._6VtqdG_formLabel{flex:none}._6VtqdG_filterBar ._6VtqdG_select{flex:none;max-width:150px}._6VtqdG_filterBar ._6VtqdG_segmented{flex:none}._6VtqdG_titleIcon{vertical-align:-2px;opacity:.8;margin-right:2px;display:inline-block}._6VtqdG_grow{flex:1}._6VtqdG_hintLine{opacity:.55;margin:0;font-size:11.5px}._6VtqdG_hintPadded{margin:6px 12px 2px}._6VtqdG_hintInline{margin:4px 2px}._6VtqdG_rowMuted{cursor:default;opacity:.55}._6VtqdG_actionsPadded{padding:8px 12px}._6VtqdG_actionsTop{margin-top:8px}._6VtqdG_actionsBottom{margin-bottom:8px}._6VtqdG_groupTime{margin-left:6px}._6VtqdG_sectionHeadRow{align-items:center;gap:8px;display:flex}._6VtqdG_sectionTitleFill{flex:1}._6VtqdG_dialogSelect{width:100%;margin-bottom:12px}._6VtqdG_dialogRow{align-items:center;gap:8px;display:flex}._6VtqdG_workspaceBox{align-items:center;gap:6px;display:inline-flex}._6VtqdG_workspaceInput{width:200px;padding:6px 10px;font-size:12px}._6VtqdG_projectNest{border-left:1px solid #80808024;flex-direction:column;margin:2px 0 0 14px;display:flex}._6VtqdG_dragHandle{cursor:grab;opacity:.28;letter-spacing:0;user-select:none;flex:none;justify-content:center;align-self:center;align-items:center;width:8px;height:16px;padding:0 1px;font-size:10px;display:inline-flex;overflow:hidden}._6VtqdG_dragHandle:active{cursor:grabbing}._6VtqdG_dragging{opacity:.45}._6VtqdG_dragOver{outline:2px dashed var(--hub-model,#2f81f7);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{background:#8080800f;border:.5px solid #80808021;border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:#80808021;border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-model,#2f81f7);height:100%;transition:width .2s}";
|
|
2766
|
+
const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;color-scheme:light dark;--hub-model:#2f81f7;--hub-user:#3fb950;flex-direction:column;gap:14px;max-width:720px;margin:0 auto;padding:28px 20px 44px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Helvetica Neue,sans-serif;display:flex}._6VtqdG_header{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}._6VtqdG_title{letter-spacing:-.02em;margin:0;font-size:24px;font-weight:700}._6VtqdG_hint{opacity:.5;font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:#80808024;border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:inherit;opacity:.62;cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{opacity:.9}._6VtqdG_segBtnActive{opacity:1;background:#80808047;font-weight:600}._6VtqdG_search{width:100%;color:inherit;background:#8080801f;border:none;border-radius:10px;outline:none;padding:10px 14px;font-size:13px;transition:background .15s}._6VtqdG_search::placeholder{opacity:.45}._6VtqdG_search:focus{background:#8080802e}._6VtqdG_section{background:#8080800f;border-radius:12px;flex-direction:column;margin-top:4px;display:flex;overflow:hidden;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_sectionTitle{margin:14px 16px 2px;font-size:13px;font-weight:700}._6VtqdG_groupHead{box-sizing:border-box;align-items:center;gap:8px;min-height:44px;padding:10px 14px;display:flex}._6VtqdG_groupTitle{opacity:.92;flex:1;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:600;line-height:1;display:inline-flex}._6VtqdG_groupOps{flex-wrap:wrap;flex:none;align-items:center;gap:6px;display:inline-flex}._6VtqdG_opBtn{color:inherit;cursor:pointer;background:#80808021;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:#80808038}._6VtqdG_opBtn:disabled{opacity:.4;cursor:default}._6VtqdG_row{cursor:pointer;background:0 0;align-items:center;gap:12px;padding:10px 14px;transition:background .12s;display:flex}._6VtqdG_row:hover{background:#80808014}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-model);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid #80808021}._6VtqdG_rowMain{flex:1;min-width:0}._6VtqdG_rowName{align-items:center;gap:5px;font-size:13.5px;display:flex}._6VtqdG_rowNameText{font-weight:600}._6VtqdG_rowDesc{opacity:.52;white-space:nowrap;text-overflow:ellipsis;margin-top:1px;font-size:12.5px;overflow:hidden}._6VtqdG_badges{flex:none;align-items:center;gap:6px;display:flex}._6VtqdG_badge{opacity:.8;white-space:nowrap;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{cursor:pointer;background:#8080804d;border:none;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:#34c759}._6VtqdG_switchThumb{background:#fff;border-radius:50%;width:17px;height:17px;transition:transform .18s;display:block;transform:translate(0);box-shadow:0 1px 2px #00000040}._6VtqdG_switchOn ._6VtqdG_switchThumb{transform:translate(15px)}._6VtqdG_empty{opacity:.5;text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{background:#d299220f;border-left:3px solid #d29922;padding:9px 14px;font-size:12px}._6VtqdG_diagPath{opacity:.75;word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{opacity:.65;margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:#d1242f;white-space:pre-wrap;word-break:break-all;background:#d1242f12;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_successBanner{color:#3fb950;white-space:pre-wrap;word-break:break-all;background:#3fb95014;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_detailHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}._6VtqdG_back{color:inherit;cursor:pointer;background:#8080801f;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:#80808033}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{opacity:.6;flex-direction:column;gap:4px;font-size:12px;display:flex}._6VtqdG_detailMetaLine{word-break:break-all}._6VtqdG_detailContent{white-space:pre-wrap;word-break:break-word;background:#8080800d;border-radius:12px;max-height:62vh;padding:14px 16px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.6;overflow:auto}._6VtqdG_form{background:#8080800d;border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_formRow{flex-direction:column;gap:5px;display:flex}._6VtqdG_formLabel{opacity:.6;font-size:12px}._6VtqdG_input,._6VtqdG_select{color:inherit;background:#8080801f;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:#8080802e}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;color:inherit;background:#8080801f;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:#80808033}._6VtqdG_primary{background:var(--hub-model);color:#fff}._6VtqdG_primary:hover{opacity:.92;background:#2f81f7}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{color:#fff;background:#d1242f}._6VtqdG_danger:hover{opacity:.92;background:#d1242f}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:#d1242f}._6VtqdG_formSuccess{color:#3fb950}._6VtqdG_muted{opacity:.55}._6VtqdG_dot{vertical-align:middle;border-radius:50%;width:7px;height:7px;margin-left:5px;display:inline-block}._6VtqdG_dotModel{background:var(--hub-model)}._6VtqdG_dotUser{background:var(--hub-user)}._6VtqdG_displayName{opacity:.55;white-space:nowrap;text-overflow:ellipsis;flex-shrink:1;min-width:0;max-width:160px;margin-left:6px;font-size:11px;font-weight:400;overflow:hidden}._6VtqdG_legend{opacity:.55;flex-wrap:wrap;align-items:center;gap:12px;padding:2px 2px 0;font-size:11.5px;display:flex}._6VtqdG_legendItem{align-items:center;gap:4px;display:inline-flex}._6VtqdG_legendItem ._6VtqdG_dot{margin-left:0}._6VtqdG_legendHint{opacity:.8}._6VtqdG_badgeSource,._6VtqdG_badgeCount{opacity:.72;background:#8080801a;border:none}._6VtqdG_disclosure{min-width:0;color:inherit;cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:7px;min-height:24px;padding:2px 0;display:flex}._6VtqdG_disclosure:hover ._6VtqdG_groupTitle{opacity:1}._6VtqdG_chevron{opacity:.55;border-bottom:1.5px solid;border-right:1.5px solid;flex:none;align-self:center;width:8px;height:8px;margin-right:2px;transition:transform .15s;transform:rotate(45deg)translateY(-1px)}._6VtqdG_chevronCollapsed{transform:rotate(-45deg)translateY(-1px)}._6VtqdG_headerCount{opacity:.5;white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{opacity:.45;white-space:nowrap;font-variant-numeric:tabular-nums;margin-left:6px;font-size:12px;font-weight:500}._6VtqdG_subbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_legendToggle{width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;background:#80808024;border:none;border-radius:50%;flex:none;font-size:12px;line-height:1;transition:opacity .15s,background .15s}._6VtqdG_legendToggle:hover{opacity:1}._6VtqdG_legendToggleActive{opacity:1;background:#80808047}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:#d29922;vertical-align:1px;background:#d299221f;border-radius:999px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:700;line-height:1.6;display:inline-block}._6VtqdG_useTime{opacity:.45;white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773}._6VtqdG_switchMixed ._6VtqdG_switchThumb{transform:translate(7.5px);box-shadow:0 1px 2px #00000040}._6VtqdG_groupTitleInner{align-items:baseline;display:inline-flex}._6VtqdG_sourceLink{color:inherit;opacity:.9;border-bottom:1px dotted;font-weight:600;text-decoration:none}._6VtqdG_sourceLink:hover{opacity:1}._6VtqdG_statusBadges{flex:none;align-items:center;gap:4px;display:inline-flex}._6VtqdG_statusBadge{opacity:.8;white-space:nowrap;background:#8080801a;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:#3fb950;background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:#d29922;background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:#d1242f;background:#d1242f14;border-color:currentColor}._6VtqdG_statusWrap{cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;padding:0;font-family:inherit;display:inline-flex}._6VtqdG_statusWrap:hover ._6VtqdG_statusBadge{opacity:1}._6VtqdG_statusButton{cursor:pointer;font-family:inherit}._6VtqdG_statusButton:hover{opacity:1}._6VtqdG_opDanger{color:#d1242f;background:#d1242f1a}._6VtqdG_opDanger:hover{background:#d1242f2e}._6VtqdG_iconBtn{border-radius:999px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}._6VtqdG_sourceCard{background:#8080800d;border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;font-size:12px;display:flex}._6VtqdG_sourceCardTitle{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_dialogOverlay{z-index:50;-webkit-backdrop-filter:blur(2px);background:#00000059;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}._6VtqdG_dialog{background:var(--dsw-surface,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-text,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}@media (prefers-color-scheme:dark){._6VtqdG_dialog{color:#f5f5f7;background:#2c2c2e}}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{opacity:.65;margin:0 0 10px;font-size:12.5px;line-height:1.5}._6VtqdG_dialogList{flex-direction:column;gap:5px;max-height:200px;margin:0 0 14px;padding:0;list-style:none;display:flex;overflow:auto}._6VtqdG_dialogList li{opacity:.85;word-break:break-all;font-size:12.5px}._6VtqdG_dialogActions{justify-content:flex-end;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_search{flex:1;min-width:160px}._6VtqdG_filterBar ._6VtqdG_formLabel{flex:none}._6VtqdG_filterBar ._6VtqdG_select{flex:none;max-width:150px}._6VtqdG_filterBar ._6VtqdG_segmented{flex:none}._6VtqdG_titleIcon{vertical-align:-2px;opacity:.8;margin-right:2px;display:inline-block}._6VtqdG_grow{flex:1}._6VtqdG_hintLine{opacity:.55;margin:0;font-size:11.5px}._6VtqdG_hintPadded{margin:6px 12px 2px}._6VtqdG_hintInline{margin:4px 2px}._6VtqdG_rowMuted{cursor:default;opacity:.55}._6VtqdG_actionsPadded{padding:8px 12px}._6VtqdG_actionsTop{margin-top:8px}._6VtqdG_groupTime{margin-left:6px}._6VtqdG_sectionHeadRow{align-items:center;gap:8px;display:flex}._6VtqdG_sectionTitleFill{flex:1}._6VtqdG_dialogSelect{width:100%;margin-bottom:12px}._6VtqdG_dialogRow{align-items:center;gap:8px;display:flex}._6VtqdG_workspaceBox{align-items:center;gap:6px;display:inline-flex}._6VtqdG_workspaceInput{width:200px;padding:6px 10px;font-size:12px}._6VtqdG_projectNest{border-left:1px solid #80808024;flex-direction:column;margin:2px 0 0 14px;display:flex}._6VtqdG_dragHandle{cursor:grab;opacity:.28;letter-spacing:0;user-select:none;flex:none;justify-content:center;align-self:center;align-items:center;width:8px;height:16px;padding:0 1px;font-size:10px;display:inline-flex;overflow:hidden}._6VtqdG_dragHandle:active{cursor:grabbing}._6VtqdG_dragging{opacity:.45}._6VtqdG_dragOver{outline:2px dashed var(--hub-model,#2f81f7);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{background:#8080800f;border:.5px solid #80808021;border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:#80808021;border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-model,#2f81f7);height:100%;transition:width .2s}";
|
|
2662
2767
|
const tagId = "dsh-skill-hub/panel.module.css";
|
|
2663
2768
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2664
2769
|
const tag = document.createElement("style");
|
|
@@ -2669,18 +2774,13 @@ window.__ModuleLoader__.load({
|
|
|
2669
2774
|
}
|
|
2670
2775
|
var panel_module_css_default = {
|
|
2671
2776
|
"actions": "_6VtqdG_actions",
|
|
2672
|
-
"actionsBottom": "_6VtqdG_actionsBottom",
|
|
2673
2777
|
"actionsPadded": "_6VtqdG_actionsPadded",
|
|
2674
2778
|
"actionsTop": "_6VtqdG_actionsTop",
|
|
2675
2779
|
"back": "_6VtqdG_back",
|
|
2676
2780
|
"badge": "_6VtqdG_badge",
|
|
2677
2781
|
"badgeCount": "_6VtqdG_badgeCount",
|
|
2678
|
-
"badgeDisabled": "_6VtqdG_badgeDisabled",
|
|
2679
|
-
"badgeModel": "_6VtqdG_badgeModel",
|
|
2680
2782
|
"badgeReadonly": "_6VtqdG_badgeReadonly",
|
|
2681
2783
|
"badgeSource": "_6VtqdG_badgeSource",
|
|
2682
|
-
"badgeUser": "_6VtqdG_badgeUser",
|
|
2683
|
-
"badgeUses": "_6VtqdG_badgeUses",
|
|
2684
2784
|
"badges": "_6VtqdG_badges",
|
|
2685
2785
|
"button": "_6VtqdG_button",
|
|
2686
2786
|
"buttons": "_6VtqdG_buttons",
|
|
@@ -2704,6 +2804,7 @@ window.__ModuleLoader__.load({
|
|
|
2704
2804
|
"dialogText": "_6VtqdG_dialogText",
|
|
2705
2805
|
"dialogTitle": "_6VtqdG_dialogTitle",
|
|
2706
2806
|
"disclosure": "_6VtqdG_disclosure",
|
|
2807
|
+
"displayName": "_6VtqdG_displayName",
|
|
2707
2808
|
"dot": "_6VtqdG_dot",
|
|
2708
2809
|
"dotModel": "_6VtqdG_dotModel",
|
|
2709
2810
|
"dotUser": "_6VtqdG_dotUser",
|
|
@@ -2747,7 +2848,6 @@ window.__ModuleLoader__.load({
|
|
|
2747
2848
|
"row": "_6VtqdG_row",
|
|
2748
2849
|
"rowDesc": "_6VtqdG_rowDesc",
|
|
2749
2850
|
"rowMain": "_6VtqdG_rowMain",
|
|
2750
|
-
"rowMeta": "_6VtqdG_rowMeta",
|
|
2751
2851
|
"rowMuted": "_6VtqdG_rowMuted",
|
|
2752
2852
|
"rowName": "_6VtqdG_rowName",
|
|
2753
2853
|
"rowNameText": "_6VtqdG_rowNameText",
|
|
@@ -2845,32 +2945,108 @@ window.__ModuleLoader__.load({
|
|
|
2845
2945
|
}
|
|
2846
2946
|
//#endregion
|
|
2847
2947
|
//#region src/client/panel/SkillDetailView.tsx
|
|
2948
|
+
/**
|
|
2949
|
+
* Full-page skill detail view: metadata, upstream source card with
|
|
2950
|
+
* check/sync/follow-delete actions, and the raw SKILL.md body. Pure
|
|
2951
|
+
* presentation — every state value and action arrives as a prop, so the
|
|
2952
|
+
* panel stays the single owner of state.
|
|
2953
|
+
*/
|
|
2848
2954
|
function SkillDetailView(props) {
|
|
2849
|
-
const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, onBack, onCheck, onSync, onFollowDelete } = props;
|
|
2955
|
+
const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, disabled, onEnable, onBack, onCheck, onSync, onFollowDelete } = props;
|
|
2850
2956
|
const detailSource = sourcesState?.sources.find((source) => source.skills.includes(detail.name));
|
|
2851
2957
|
const detailCheck = detailSource !== void 0 ? sourceCheck[detailSource.repo] : void 0;
|
|
2958
|
+
const [copied, setCopied] = (0, react.useState)(null);
|
|
2959
|
+
const copyTimer = (0, react.useRef)(void 0);
|
|
2960
|
+
(0, react.useEffect)(() => () => {
|
|
2961
|
+
window.clearTimeout(copyTimer.current);
|
|
2962
|
+
}, []);
|
|
2963
|
+
const copyText = (text, key) => {
|
|
2964
|
+
copyTextToClipboard(text).then((ok) => {
|
|
2965
|
+
if (!ok) return;
|
|
2966
|
+
setCopied(key);
|
|
2967
|
+
window.clearTimeout(copyTimer.current);
|
|
2968
|
+
copyTimer.current = window.setTimeout(() => {
|
|
2969
|
+
setCopied(null);
|
|
2970
|
+
}, 1200);
|
|
2971
|
+
});
|
|
2972
|
+
};
|
|
2852
2973
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2853
2974
|
className: panel_module_css_default.panel,
|
|
2854
2975
|
children: [
|
|
2855
2976
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2856
2977
|
className: panel_module_css_default.detailHead,
|
|
2857
|
-
children: [
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
className: panel_module_css_default.
|
|
2866
|
-
style:
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2978
|
+
children: [
|
|
2979
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2980
|
+
type: "button",
|
|
2981
|
+
className: panel_module_css_default.back,
|
|
2982
|
+
onClick: onBack,
|
|
2983
|
+
children: tt("detail.back")
|
|
2984
|
+
}),
|
|
2985
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2986
|
+
className: panel_module_css_default.detailName,
|
|
2987
|
+
style: {
|
|
2988
|
+
display: "inline-flex",
|
|
2989
|
+
alignItems: "center",
|
|
2990
|
+
gap: 6,
|
|
2991
|
+
flexWrap: "wrap"
|
|
2992
|
+
},
|
|
2993
|
+
children: [
|
|
2994
|
+
detail.name,
|
|
2995
|
+
isDisplayNameDistinct(detail.name, detail.displayName) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2996
|
+
className: panel_module_css_default.displayName,
|
|
2997
|
+
style: {
|
|
2998
|
+
fontSize: 13,
|
|
2999
|
+
marginLeft: 0
|
|
3000
|
+
},
|
|
3001
|
+
children: detail.displayName
|
|
3002
|
+
}) : null,
|
|
3003
|
+
detail.invocation.modelInvocable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3004
|
+
className: panel_module_css_default.dot + " " + panel_module_css_default.dotModel,
|
|
3005
|
+
style: dotStyle(hubConfig?.dotModelColor),
|
|
3006
|
+
title: tt("legend.model")
|
|
3007
|
+
}) : detail.invocation.userInvocable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3008
|
+
className: panel_module_css_default.dot + " " + panel_module_css_default.dotUser,
|
|
3009
|
+
style: dotStyle(hubConfig?.dotUserColor),
|
|
3010
|
+
title: tt("legend.user")
|
|
3011
|
+
}) : null
|
|
3012
|
+
]
|
|
3013
|
+
}),
|
|
3014
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3015
|
+
className: panel_module_css_default.actions,
|
|
3016
|
+
style: {
|
|
3017
|
+
marginLeft: "auto",
|
|
3018
|
+
gap: 6
|
|
3019
|
+
},
|
|
3020
|
+
children: [
|
|
3021
|
+
disabled === true && onEnable !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3022
|
+
type: "button",
|
|
3023
|
+
className: panel_module_css_default.opBtn,
|
|
3024
|
+
role: "switch",
|
|
3025
|
+
"aria-checked": false,
|
|
3026
|
+
"aria-label": tt("row.enable"),
|
|
3027
|
+
onClick: onEnable,
|
|
3028
|
+
children: tt("row.enable")
|
|
3029
|
+
}) : null,
|
|
3030
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3031
|
+
type: "button",
|
|
3032
|
+
className: panel_module_css_default.opBtn,
|
|
3033
|
+
onClick: () => {
|
|
3034
|
+
copyText("$" + detail.name, "mention");
|
|
3035
|
+
},
|
|
3036
|
+
children: copied === "mention" ? tt("detail.copied") : tt("detail.copyMention")
|
|
3037
|
+
}),
|
|
3038
|
+
detail.path !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3039
|
+
type: "button",
|
|
3040
|
+
className: panel_module_css_default.opBtn,
|
|
3041
|
+
onClick: () => {
|
|
3042
|
+
const path = detail.path;
|
|
3043
|
+
if (path !== void 0) copyText(path, "path");
|
|
3044
|
+
},
|
|
3045
|
+
children: copied === "path" ? tt("detail.copied") : tt("detail.copyPath")
|
|
3046
|
+
}) : null
|
|
3047
|
+
]
|
|
3048
|
+
})
|
|
3049
|
+
]
|
|
2874
3050
|
}),
|
|
2875
3051
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2876
3052
|
className: panel_module_css_default.detailMeta,
|
|
@@ -2972,34 +3148,30 @@ window.__ModuleLoader__.load({
|
|
|
2972
3148
|
}),
|
|
2973
3149
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2974
3150
|
className: panel_module_css_default.buttons + " " + panel_module_css_default.actionsTop,
|
|
2975
|
-
children: [
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
},
|
|
3000
|
-
children: tt("source.followDelete")
|
|
3001
|
-
}) : null
|
|
3002
|
-
]
|
|
3151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3152
|
+
type: "button",
|
|
3153
|
+
className: panel_module_css_default.opBtn,
|
|
3154
|
+
disabled: checkingSource !== null,
|
|
3155
|
+
onClick: () => {
|
|
3156
|
+
onCheck(detailSource.repo);
|
|
3157
|
+
},
|
|
3158
|
+
children: checkingSource === detailSource.repo ? tt("source.checking") : tt("source.check")
|
|
3159
|
+
}), disabled !== true ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3160
|
+
type: "button",
|
|
3161
|
+
className: panel_module_css_default.opBtn,
|
|
3162
|
+
disabled: syncingSource !== null,
|
|
3163
|
+
onClick: () => {
|
|
3164
|
+
onSync(detailSource.repo, [detail.name]);
|
|
3165
|
+
},
|
|
3166
|
+
children: syncingSource === detailSource.repo ? tt("source.syncing") : tt("source.sync")
|
|
3167
|
+
}), detailCheck?.deleted.includes(detail.name) === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3168
|
+
type: "button",
|
|
3169
|
+
className: panel_module_css_default.opBtn + " " + panel_module_css_default.opDanger,
|
|
3170
|
+
onClick: () => {
|
|
3171
|
+
onFollowDelete(detailSource.repo, [detail.name]);
|
|
3172
|
+
},
|
|
3173
|
+
children: tt("source.followDelete")
|
|
3174
|
+
}) : null] }) : null]
|
|
3003
3175
|
})
|
|
3004
3176
|
]
|
|
3005
3177
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -3136,6 +3308,7 @@ window.__ModuleLoader__.load({
|
|
|
3136
3308
|
const stat = hub.uses.get(skill.name);
|
|
3137
3309
|
const count = stat?.count ?? 0;
|
|
3138
3310
|
const lastUsed = stat?.lastUsed;
|
|
3311
|
+
const isDuplicate = hub.catalog?.duplicateNames?.includes(skill.name) === true;
|
|
3139
3312
|
/** 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */
|
|
3140
3313
|
const dot = skill.invocation.modelInvocable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3141
3314
|
className: panel_module_css_default.dot + " " + panel_module_css_default.dotModel,
|
|
@@ -3172,11 +3345,21 @@ window.__ModuleLoader__.load({
|
|
|
3172
3345
|
className: panel_module_css_default.rowNameText,
|
|
3173
3346
|
children: skill.name
|
|
3174
3347
|
}),
|
|
3348
|
+
isDisplayNameDistinct(skill.name, skill.displayName) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3349
|
+
className: panel_module_css_default.displayName,
|
|
3350
|
+
title: skill.displayName,
|
|
3351
|
+
children: skill.displayName
|
|
3352
|
+
}) : null,
|
|
3175
3353
|
count > 0 && hub.hubConfig?.showUseCount !== false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3176
3354
|
className: panel_module_css_default.useCount,
|
|
3177
3355
|
children: count
|
|
3178
3356
|
}) : null,
|
|
3179
3357
|
dot,
|
|
3358
|
+
isDuplicate ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3359
|
+
className: panel_module_css_default.badge + " " + panel_module_css_default.statusError,
|
|
3360
|
+
title: tt("row.duplicateHint"),
|
|
3361
|
+
children: tt("row.duplicate")
|
|
3362
|
+
}) : null,
|
|
3180
3363
|
lastUsed !== void 0 && hub.hubConfig?.showUseTime !== false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3181
3364
|
className: panel_module_css_default.useTime,
|
|
3182
3365
|
children: relativeTimeText(lastUsed)
|
|
@@ -3184,7 +3367,8 @@ window.__ModuleLoader__.load({
|
|
|
3184
3367
|
]
|
|
3185
3368
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3186
3369
|
className: panel_module_css_default.rowDesc,
|
|
3187
|
-
|
|
3370
|
+
title: skill.description,
|
|
3371
|
+
children: skill.shortDescription ?? skill.description
|
|
3188
3372
|
})]
|
|
3189
3373
|
}), skill.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3190
3374
|
type: "button",
|
|
@@ -3222,17 +3406,36 @@ window.__ModuleLoader__.load({
|
|
|
3222
3406
|
return tt("badge.source." + root);
|
|
3223
3407
|
}
|
|
3224
3408
|
function DisabledRow(props) {
|
|
3225
|
-
const { record, busy, onEnable } = props;
|
|
3409
|
+
const { record, busy, onEnable, duplicate, onOpen } = props;
|
|
3410
|
+
/** 键盘打开详情:Enter 或空格。仅当焦点在行本身(而非行内开关)时生效。 */
|
|
3411
|
+
const onKeyDown = (event) => {
|
|
3412
|
+
if (onOpen === void 0 || event.target !== event.currentTarget) return;
|
|
3413
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
3414
|
+
event.preventDefault();
|
|
3415
|
+
onOpen();
|
|
3416
|
+
}
|
|
3417
|
+
};
|
|
3226
3418
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3227
|
-
className: panel_module_css_default.row + " " + panel_module_css_default.rowStatic,
|
|
3419
|
+
className: panel_module_css_default.row + (onOpen === void 0 ? " " + panel_module_css_default.rowStatic : ""),
|
|
3420
|
+
role: onOpen === void 0 ? void 0 : "button",
|
|
3421
|
+
tabIndex: onOpen === void 0 ? void 0 : 0,
|
|
3422
|
+
"aria-label": onOpen === void 0 ? void 0 : tt("row.open", { name: record.name }),
|
|
3423
|
+
onClick: onOpen,
|
|
3424
|
+
onKeyDown,
|
|
3228
3425
|
children: [
|
|
3229
3426
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3230
3427
|
className: panel_module_css_default.rowMain,
|
|
3231
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
3428
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3232
3429
|
className: panel_module_css_default.rowName,
|
|
3233
|
-
children: record.name
|
|
3430
|
+
children: [record.name, duplicate === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3431
|
+
className: panel_module_css_default.badge + " " + panel_module_css_default.statusError,
|
|
3432
|
+
style: { marginLeft: 6 },
|
|
3433
|
+
title: tt("row.duplicateHint"),
|
|
3434
|
+
children: tt("row.duplicate")
|
|
3435
|
+
}) : null]
|
|
3234
3436
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3235
3437
|
className: panel_module_css_default.rowDesc,
|
|
3438
|
+
title: record.description,
|
|
3236
3439
|
children: record.description
|
|
3237
3440
|
})]
|
|
3238
3441
|
}),
|
|
@@ -3250,7 +3453,10 @@ window.__ModuleLoader__.load({
|
|
|
3250
3453
|
"aria-label": tt("row.enable"),
|
|
3251
3454
|
className: panel_module_css_default.switch,
|
|
3252
3455
|
disabled: busy,
|
|
3253
|
-
onClick:
|
|
3456
|
+
onClick: (event) => {
|
|
3457
|
+
event.stopPropagation();
|
|
3458
|
+
onEnable();
|
|
3459
|
+
},
|
|
3254
3460
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.switchThumb })
|
|
3255
3461
|
})
|
|
3256
3462
|
]
|
|
@@ -3607,8 +3813,12 @@ window.__ModuleLoader__.load({
|
|
|
3607
3813
|
}, skill.name)), disabledMembers.map((record) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DisabledRow, {
|
|
3608
3814
|
record,
|
|
3609
3815
|
busy: busyNames.has(record.name),
|
|
3816
|
+
duplicate: catalog?.duplicateNames?.includes(record.name) === true,
|
|
3610
3817
|
onEnable: () => {
|
|
3611
3818
|
enableDisabled(record);
|
|
3819
|
+
},
|
|
3820
|
+
onOpen: () => {
|
|
3821
|
+
hub.openDetail(record.name);
|
|
3612
3822
|
}
|
|
3613
3823
|
}, record.name))] }) : null]
|
|
3614
3824
|
}, "col:" + collection.name);
|
|
@@ -3694,8 +3904,12 @@ window.__ModuleLoader__.load({
|
|
|
3694
3904
|
}, skill.name)), personalDisabled.map((record) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DisabledRow, {
|
|
3695
3905
|
record,
|
|
3696
3906
|
busy: busyNames.has(record.name),
|
|
3907
|
+
duplicate: catalog?.duplicateNames?.includes(record.name) === true,
|
|
3697
3908
|
onEnable: () => {
|
|
3698
3909
|
enableDisabled(record);
|
|
3910
|
+
},
|
|
3911
|
+
onOpen: () => {
|
|
3912
|
+
hub.openDetail(record.name);
|
|
3699
3913
|
}
|
|
3700
3914
|
}, record.name))] }) : null]
|
|
3701
3915
|
}, "uncategorized-source");
|
|
@@ -3849,8 +4063,12 @@ window.__ModuleLoader__.load({
|
|
|
3849
4063
|
}, skill.name)), disabledMembers.map((record) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DisabledRow, {
|
|
3850
4064
|
record,
|
|
3851
4065
|
busy: busyNames.has(record.name),
|
|
4066
|
+
duplicate: hub.catalog?.duplicateNames?.includes(record.name) === true,
|
|
3852
4067
|
onEnable: () => {
|
|
3853
4068
|
enableDisabled(record);
|
|
4069
|
+
},
|
|
4070
|
+
onOpen: () => {
|
|
4071
|
+
hub.openDetail(record.name);
|
|
3854
4072
|
}
|
|
3855
4073
|
}, record.name))] }) : null]
|
|
3856
4074
|
}, "tag:" + tag.id);
|
|
@@ -4030,6 +4248,89 @@ window.__ModuleLoader__.load({
|
|
|
4030
4248
|
]
|
|
4031
4249
|
});
|
|
4032
4250
|
}
|
|
4251
|
+
/** Version picker: switch a market source's tracked ref (release / branch / custom). */
|
|
4252
|
+
function VersionChoiceDialog(props) {
|
|
4253
|
+
const { choice, busy, onSelect, onCustom, onCancel, onConfirm } = props;
|
|
4254
|
+
const effective = choice.custom.trim() !== "" ? choice.custom.trim() : choice.selected;
|
|
4255
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DialogShell, {
|
|
4256
|
+
onClose: onCancel,
|
|
4257
|
+
children: [
|
|
4258
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
4259
|
+
className: panel_module_css_default.dialogTitle,
|
|
4260
|
+
children: tt("market.versionTitle")
|
|
4261
|
+
}),
|
|
4262
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
4263
|
+
className: panel_module_css_default.dialogText,
|
|
4264
|
+
children: [tt("market.versionText", { repo: choice.repo }), choice.current !== void 0 ? ` (${tt("market.versionCurrent", { ref: choice.current })})` : ""]
|
|
4265
|
+
}),
|
|
4266
|
+
choice.loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4267
|
+
className: panel_module_css_default.dialogText,
|
|
4268
|
+
children: tt("market.scanning")
|
|
4269
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4270
|
+
choice.releases.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4271
|
+
className: panel_module_css_default.dialogText,
|
|
4272
|
+
style: { marginBottom: 4 },
|
|
4273
|
+
children: tt("market.versionReleases")
|
|
4274
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
4275
|
+
className: panel_module_css_default.select + " " + panel_module_css_default.dialogSelect,
|
|
4276
|
+
value: choice.releases.includes(choice.selected) ? choice.selected : choice.releases[0],
|
|
4277
|
+
onChange: (event) => {
|
|
4278
|
+
onSelect(event.target.value);
|
|
4279
|
+
onCustom("");
|
|
4280
|
+
},
|
|
4281
|
+
children: choice.releases.map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
4282
|
+
value: tag,
|
|
4283
|
+
children: tag
|
|
4284
|
+
}, tag))
|
|
4285
|
+
})] }) : null,
|
|
4286
|
+
choice.branches.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4287
|
+
className: panel_module_css_default.dialogText,
|
|
4288
|
+
style: { marginBottom: 4 },
|
|
4289
|
+
children: tt("market.versionBranches")
|
|
4290
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
4291
|
+
className: panel_module_css_default.select + " " + panel_module_css_default.dialogSelect,
|
|
4292
|
+
value: choice.branches.includes(choice.selected) ? choice.selected : choice.branches[0],
|
|
4293
|
+
onChange: (event) => {
|
|
4294
|
+
onSelect(event.target.value);
|
|
4295
|
+
onCustom("");
|
|
4296
|
+
},
|
|
4297
|
+
children: choice.branches.map((branch) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
4298
|
+
value: branch,
|
|
4299
|
+
children: branch
|
|
4300
|
+
}, branch))
|
|
4301
|
+
})] }) : null,
|
|
4302
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4303
|
+
className: panel_module_css_default.dialogText,
|
|
4304
|
+
style: { marginBottom: 4 },
|
|
4305
|
+
children: tt("market.versionCustom")
|
|
4306
|
+
}),
|
|
4307
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4308
|
+
className: panel_module_css_default.input + " " + panel_module_css_default.dialogSelect,
|
|
4309
|
+
value: choice.custom,
|
|
4310
|
+
onChange: (event) => {
|
|
4311
|
+
onCustom(event.target.value);
|
|
4312
|
+
},
|
|
4313
|
+
placeholder: "v1.2.3 / main / abc1234"
|
|
4314
|
+
})
|
|
4315
|
+
] }),
|
|
4316
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4317
|
+
className: panel_module_css_default.dialogActions,
|
|
4318
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4319
|
+
type: "button",
|
|
4320
|
+
className: panel_module_css_default.button,
|
|
4321
|
+
onClick: onCancel,
|
|
4322
|
+
children: tt("form.cancel")
|
|
4323
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4324
|
+
type: "button",
|
|
4325
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.primary,
|
|
4326
|
+
disabled: busy || choice.loading || effective === "",
|
|
4327
|
+
onClick: onConfirm,
|
|
4328
|
+
children: busy ? tt("source.syncing") : tt("market.versionConfirm", { ref: effective })
|
|
4329
|
+
})]
|
|
4330
|
+
})
|
|
4331
|
+
]
|
|
4332
|
+
});
|
|
4333
|
+
}
|
|
4033
4334
|
/** Post-sync selection: which tracked skills to batch-update to the new version. */
|
|
4034
4335
|
function MarketSyncDialog(props) {
|
|
4035
4336
|
const { dialog, busy, onToggle, onCancel, onConfirm } = props;
|
|
@@ -4170,10 +4471,19 @@ window.__ModuleLoader__.load({
|
|
|
4170
4471
|
rel: "noreferrer",
|
|
4171
4472
|
children: record.repo
|
|
4172
4473
|
}),
|
|
4173
|
-
|
|
4474
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4475
|
+
type: "button",
|
|
4174
4476
|
className: panel_module_css_default.badge + " " + panel_module_css_default.badgeSource,
|
|
4175
|
-
|
|
4176
|
-
|
|
4477
|
+
style: {
|
|
4478
|
+
cursor: "pointer",
|
|
4479
|
+
fontFamily: "inherit"
|
|
4480
|
+
},
|
|
4481
|
+
title: tt("market.versionHint"),
|
|
4482
|
+
onClick: () => {
|
|
4483
|
+
hub.openVersionDialog(record.repo);
|
|
4484
|
+
},
|
|
4485
|
+
children: record.ref ?? tt("market.unpinned")
|
|
4486
|
+
}),
|
|
4177
4487
|
installedCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4178
4488
|
className: panel_module_css_default.badge + " " + panel_module_css_default.badgeCount,
|
|
4179
4489
|
children: tt("market.installed", { count: installedCount })
|
|
@@ -4422,279 +4732,291 @@ window.__ModuleLoader__.load({
|
|
|
4422
4732
|
return true;
|
|
4423
4733
|
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
4424
4734
|
const paged = filtered.slice(0, visibleCount);
|
|
4425
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
(() => {
|
|
4437
|
-
const order = /* @__PURE__ */ new Map([["skills", 0], ["design-templates", 1]]);
|
|
4438
|
-
const roots = [...new Set(entries.map((e) => e.root))].sort((a, b) => {
|
|
4439
|
-
const ao = order.get(a) ?? 99;
|
|
4440
|
-
const bo = order.get(b) ?? 99;
|
|
4441
|
-
return ao !== bo ? ao - bo : a.localeCompare(b);
|
|
4442
|
-
});
|
|
4443
|
-
const counts = /* @__PURE__ */ new Map();
|
|
4444
|
-
for (const e of entries) counts.set(e.root, (counts.get(e.root) ?? 0) + 1);
|
|
4445
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4446
|
-
style: {
|
|
4447
|
-
display: "flex",
|
|
4448
|
-
gap: 8,
|
|
4449
|
-
marginBottom: 8,
|
|
4450
|
-
flexWrap: "wrap"
|
|
4451
|
-
},
|
|
4452
|
-
children: [
|
|
4453
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4454
|
-
className: panel_module_css_default.input,
|
|
4455
|
-
style: {
|
|
4456
|
-
flex: 1,
|
|
4457
|
-
minWidth: 140
|
|
4458
|
-
},
|
|
4459
|
-
value: repoSearch,
|
|
4460
|
-
onChange: (e) => setRepoSearch(e.target.value),
|
|
4461
|
-
placeholder: "搜索技能名…"
|
|
4462
|
-
}),
|
|
4463
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4464
|
-
type: "button",
|
|
4465
|
-
className: panel_module_css_default.button + (repoFilter === "all" ? " " + panel_module_css_default.primary : ""),
|
|
4466
|
-
style: {
|
|
4467
|
-
padding: "6px 10px",
|
|
4468
|
-
fontSize: 12
|
|
4469
|
-
},
|
|
4470
|
-
onClick: () => setRepoFilter("all"),
|
|
4471
|
-
children: ["全部 ", entries.length]
|
|
4472
|
-
}),
|
|
4473
|
-
roots.map((root) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4474
|
-
type: "button",
|
|
4475
|
-
className: panel_module_css_default.button + (repoFilter === root ? " " + panel_module_css_default.primary : ""),
|
|
4476
|
-
style: {
|
|
4477
|
-
padding: "6px 10px",
|
|
4478
|
-
fontSize: 12
|
|
4479
|
-
},
|
|
4480
|
-
onClick: () => setRepoFilter(root),
|
|
4481
|
-
children: [
|
|
4482
|
-
root,
|
|
4483
|
-
" ",
|
|
4484
|
-
counts.get(root) ?? 0
|
|
4485
|
-
]
|
|
4486
|
-
}, root))
|
|
4487
|
-
]
|
|
4488
|
-
});
|
|
4489
|
-
})(),
|
|
4490
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4491
|
-
className: panel_module_css_default.hintLine,
|
|
4735
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4736
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
4737
|
+
className: panel_module_css_default.hintLine + " " + panel_module_css_default.hintInline,
|
|
4738
|
+
children: [
|
|
4739
|
+
tt("repo.ready", { count: entries.length }),
|
|
4740
|
+
" · ",
|
|
4741
|
+
repoDiscoverState.data.ref !== null ? `ref ${repoDiscoverState.data.ref}` : ""
|
|
4742
|
+
]
|
|
4743
|
+
}),
|
|
4744
|
+
repoDiscoverState.data.truncated === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4745
|
+
className: panel_module_css_default.errorBanner,
|
|
4492
4746
|
style: {
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
gap: 8
|
|
4747
|
+
background: "rgba(210,153,34,0.08)",
|
|
4748
|
+
color: "#d29922",
|
|
4749
|
+
borderLeft: "3px solid #d29922"
|
|
4497
4750
|
},
|
|
4498
|
-
children:
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4751
|
+
children: tt("repo.truncated")
|
|
4752
|
+
}) : null,
|
|
4753
|
+
entries.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4754
|
+
className: panel_module_css_default.empty,
|
|
4755
|
+
children: tt("repo.empty")
|
|
4756
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4757
|
+
(() => {
|
|
4758
|
+
const order = /* @__PURE__ */ new Map([["skills", 0], ["design-templates", 1]]);
|
|
4759
|
+
const roots = [...new Set(entries.map((e) => e.root))].sort((a, b) => {
|
|
4760
|
+
const ao = order.get(a) ?? 99;
|
|
4761
|
+
const bo = order.get(b) ?? 99;
|
|
4762
|
+
return ao !== bo ? ao - bo : a.localeCompare(b);
|
|
4763
|
+
});
|
|
4764
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4765
|
+
for (const e of entries) counts.set(e.root, (counts.get(e.root) ?? 0) + 1);
|
|
4766
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4767
|
+
style: {
|
|
4768
|
+
display: "flex",
|
|
4769
|
+
gap: 8,
|
|
4770
|
+
marginBottom: 8,
|
|
4771
|
+
flexWrap: "wrap"
|
|
4772
|
+
},
|
|
4773
|
+
children: [
|
|
4774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4775
|
+
className: panel_module_css_default.input,
|
|
4776
|
+
style: {
|
|
4777
|
+
flex: 1,
|
|
4778
|
+
minWidth: 140
|
|
4779
|
+
},
|
|
4780
|
+
value: repoSearch,
|
|
4781
|
+
onChange: (e) => setRepoSearch(e.target.value),
|
|
4782
|
+
placeholder: "搜索技能名…"
|
|
4783
|
+
}),
|
|
4784
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4785
|
+
type: "button",
|
|
4786
|
+
className: panel_module_css_default.button + (repoFilter === "all" ? " " + panel_module_css_default.primary : ""),
|
|
4787
|
+
style: {
|
|
4788
|
+
padding: "6px 10px",
|
|
4789
|
+
fontSize: 12
|
|
4790
|
+
},
|
|
4791
|
+
onClick: () => setRepoFilter("all"),
|
|
4792
|
+
children: ["全部 ", entries.length]
|
|
4793
|
+
}),
|
|
4794
|
+
roots.map((root) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4795
|
+
type: "button",
|
|
4796
|
+
className: panel_module_css_default.button + (repoFilter === root ? " " + panel_module_css_default.primary : ""),
|
|
4797
|
+
style: {
|
|
4798
|
+
padding: "6px 10px",
|
|
4799
|
+
fontSize: 12
|
|
4800
|
+
},
|
|
4801
|
+
onClick: () => setRepoFilter(root),
|
|
4802
|
+
children: [
|
|
4803
|
+
root,
|
|
4804
|
+
" ",
|
|
4805
|
+
counts.get(root) ?? 0
|
|
4806
|
+
]
|
|
4807
|
+
}, root))
|
|
4808
|
+
]
|
|
4809
|
+
});
|
|
4810
|
+
})(),
|
|
4811
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4812
|
+
className: panel_module_css_default.hintLine,
|
|
4511
4813
|
style: {
|
|
4512
4814
|
display: "flex",
|
|
4513
|
-
|
|
4815
|
+
justifyContent: "space-between",
|
|
4816
|
+
flexWrap: "wrap",
|
|
4817
|
+
gap: 8
|
|
4514
4818
|
},
|
|
4515
|
-
children: [
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
padding: "4px 8px",
|
|
4533
|
-
fontSize: 11
|
|
4534
|
-
},
|
|
4535
|
-
onClick: () => {
|
|
4536
|
-
setRepoSelected(new Set(entries.filter((e) => !isExisting(e)).map((e) => e.path)));
|
|
4537
|
-
},
|
|
4538
|
-
children: ["全选全部 ", entries.filter((e) => !isExisting(e)).length]
|
|
4539
|
-
}),
|
|
4540
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4541
|
-
type: "button",
|
|
4542
|
-
className: panel_module_css_default.button,
|
|
4543
|
-
style: {
|
|
4544
|
-
padding: "4px 8px",
|
|
4545
|
-
fontSize: 11
|
|
4546
|
-
},
|
|
4547
|
-
onClick: () => {
|
|
4548
|
-
setRepoSelected(/* @__PURE__ */ new Set());
|
|
4549
|
-
},
|
|
4550
|
-
children: tt("repo.clearAll")
|
|
4551
|
-
})
|
|
4552
|
-
]
|
|
4553
|
-
})]
|
|
4554
|
-
}),
|
|
4555
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4556
|
-
className: panel_module_css_default.scanList,
|
|
4557
|
-
children: paged.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4558
|
-
className: panel_module_css_default.empty,
|
|
4559
|
-
style: { padding: 20 },
|
|
4560
|
-
children: "无匹配技能"
|
|
4561
|
-
}) : paged.map((entry) => {
|
|
4562
|
-
const existing = isExisting(entry);
|
|
4563
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4564
|
-
className: panel_module_css_default.row + (existing ? " " + panel_module_css_default.rowMuted : ""),
|
|
4819
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
4820
|
+
"已选 ",
|
|
4821
|
+
selected.length,
|
|
4822
|
+
"/",
|
|
4823
|
+
entries.length,
|
|
4824
|
+
" · ",
|
|
4825
|
+
formatBytes(selectedBytes),
|
|
4826
|
+
" · 显示 ",
|
|
4827
|
+
paged.length,
|
|
4828
|
+
"/",
|
|
4829
|
+
filtered.length,
|
|
4830
|
+
"(过滤后)"
|
|
4831
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4832
|
+
style: {
|
|
4833
|
+
display: "flex",
|
|
4834
|
+
gap: 6
|
|
4835
|
+
},
|
|
4565
4836
|
children: [
|
|
4566
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
4567
|
-
type: "
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
}
|
|
4837
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4838
|
+
type: "button",
|
|
4839
|
+
className: panel_module_css_default.button,
|
|
4840
|
+
style: {
|
|
4841
|
+
padding: "4px 8px",
|
|
4842
|
+
fontSize: 11
|
|
4843
|
+
},
|
|
4844
|
+
onClick: () => {
|
|
4845
|
+
setRepoSelected(new Set(filtered.filter((e) => !isExisting(e)).slice(0, visibleCount).map((e) => e.path)));
|
|
4846
|
+
},
|
|
4847
|
+
children: "全选当前显示"
|
|
4573
4848
|
}),
|
|
4574
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
count: entry.fileCount,
|
|
4586
|
-
size: formatBytes(entry.totalBytes)
|
|
4587
|
-
})
|
|
4588
|
-
]
|
|
4589
|
-
})]
|
|
4849
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4850
|
+
type: "button",
|
|
4851
|
+
className: panel_module_css_default.button,
|
|
4852
|
+
style: {
|
|
4853
|
+
padding: "4px 8px",
|
|
4854
|
+
fontSize: 11
|
|
4855
|
+
},
|
|
4856
|
+
onClick: () => {
|
|
4857
|
+
setRepoSelected(new Set(entries.filter((e) => !isExisting(e)).map((e) => e.path)));
|
|
4858
|
+
},
|
|
4859
|
+
children: ["全选全部 ", entries.filter((e) => !isExisting(e)).length]
|
|
4590
4860
|
}),
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4861
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4862
|
+
type: "button",
|
|
4863
|
+
className: panel_module_css_default.button,
|
|
4864
|
+
style: {
|
|
4865
|
+
padding: "4px 8px",
|
|
4866
|
+
fontSize: 11
|
|
4867
|
+
},
|
|
4868
|
+
onClick: () => {
|
|
4869
|
+
setRepoSelected(/* @__PURE__ */ new Set());
|
|
4870
|
+
},
|
|
4871
|
+
children: tt("repo.clearAll")
|
|
4597
4872
|
})
|
|
4598
4873
|
]
|
|
4599
|
-
}
|
|
4600
|
-
})
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4644
|
-
style: {
|
|
4645
|
-
display: "flex",
|
|
4646
|
-
alignItems: "center",
|
|
4647
|
-
gap: 8,
|
|
4648
|
-
marginBottom: 6
|
|
4649
|
-
},
|
|
4650
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4651
|
-
className: panel_module_css_default.scanProgressTrack,
|
|
4652
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4653
|
-
className: panel_module_css_default.scanProgressFill,
|
|
4654
|
-
style: { width: `${pct}%` }
|
|
4874
|
+
})]
|
|
4875
|
+
}),
|
|
4876
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4877
|
+
className: panel_module_css_default.scanList,
|
|
4878
|
+
children: paged.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4879
|
+
className: panel_module_css_default.empty,
|
|
4880
|
+
style: { padding: 20 },
|
|
4881
|
+
children: "无匹配技能"
|
|
4882
|
+
}) : paged.map((entry) => {
|
|
4883
|
+
const existing = isExisting(entry);
|
|
4884
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4885
|
+
className: panel_module_css_default.row + (existing ? " " + panel_module_css_default.rowMuted : ""),
|
|
4886
|
+
children: [
|
|
4887
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4888
|
+
type: "checkbox",
|
|
4889
|
+
checked: repoSelected.has(entry.path),
|
|
4890
|
+
disabled: existing,
|
|
4891
|
+
onChange: (event) => {
|
|
4892
|
+
toggleRepoSelected(entry.path, event.target.checked);
|
|
4893
|
+
}
|
|
4894
|
+
}),
|
|
4895
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4896
|
+
className: panel_module_css_default.rowMain,
|
|
4897
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4898
|
+
className: panel_module_css_default.rowName,
|
|
4899
|
+
children: entry.name
|
|
4900
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4901
|
+
className: panel_module_css_default.rowDesc,
|
|
4902
|
+
children: [
|
|
4903
|
+
entry.dir,
|
|
4904
|
+
" · ",
|
|
4905
|
+
tt("repo.files", {
|
|
4906
|
+
count: entry.fileCount,
|
|
4907
|
+
size: formatBytes(entry.totalBytes)
|
|
4908
|
+
})
|
|
4909
|
+
]
|
|
4910
|
+
})]
|
|
4911
|
+
}),
|
|
4912
|
+
existing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4913
|
+
className: panel_module_css_default.badge + " " + panel_module_css_default.badgeReadonly,
|
|
4914
|
+
children: tt("repo.existing")
|
|
4915
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4916
|
+
className: panel_module_css_default.badge + " " + panel_module_css_default.badgeSource,
|
|
4917
|
+
children: entry.origin
|
|
4655
4918
|
})
|
|
4656
|
-
|
|
4919
|
+
]
|
|
4920
|
+
}, entry.path);
|
|
4921
|
+
})
|
|
4922
|
+
}),
|
|
4923
|
+
visibleCount < filtered.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4924
|
+
style: {
|
|
4925
|
+
textAlign: "center",
|
|
4926
|
+
marginTop: 8
|
|
4927
|
+
},
|
|
4928
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4929
|
+
type: "button",
|
|
4930
|
+
className: panel_module_css_default.button,
|
|
4931
|
+
onClick: () => setVisibleCount((n) => n + 50),
|
|
4932
|
+
children: [
|
|
4933
|
+
"加载更多 50 (剩余 ",
|
|
4934
|
+
filtered.length - visibleCount,
|
|
4935
|
+
")"
|
|
4936
|
+
]
|
|
4937
|
+
})
|
|
4938
|
+
}) : null,
|
|
4939
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4940
|
+
className: panel_module_css_default.buttons + " " + panel_module_css_default.actionsTop,
|
|
4941
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4942
|
+
type: "button",
|
|
4943
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.primary,
|
|
4944
|
+
disabled: selected.length === 0 || repoImporting,
|
|
4945
|
+
onClick: () => {
|
|
4946
|
+
importRepo();
|
|
4947
|
+
},
|
|
4948
|
+
children: repoImporting ? tt("repo.importing") : `${tt("repo.import", { count: selected.length })} · ${formatBytes(selectedBytes)}`
|
|
4949
|
+
}), repoImporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4950
|
+
type: "button",
|
|
4951
|
+
className: panel_module_css_default.button,
|
|
4952
|
+
onClick: () => {
|
|
4953
|
+
cancelImport();
|
|
4954
|
+
},
|
|
4955
|
+
children: tt("repo.cancel")
|
|
4956
|
+
}) : null]
|
|
4957
|
+
}),
|
|
4958
|
+
repoResult !== null && repoResult.status === "running" ? (() => {
|
|
4959
|
+
const pct = repoResult.totalBytes > 0 ? Math.min(100, Math.round(repoResult.downloadedBytes / repoResult.totalBytes * 100)) : repoResult.total > 0 ? Math.round(repoResult.done / repoResult.total * 100) : 0;
|
|
4960
|
+
const speed = formatSpeed(repoResult.bytesPerSecond);
|
|
4961
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4962
|
+
className: panel_module_css_default.formSuccess + " " + panel_module_css_default.actionsTop,
|
|
4963
|
+
children: [
|
|
4964
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4657
4965
|
style: {
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4966
|
+
display: "flex",
|
|
4967
|
+
alignItems: "center",
|
|
4968
|
+
gap: 8,
|
|
4969
|
+
marginBottom: 6
|
|
4662
4970
|
},
|
|
4663
|
-
children: [
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4971
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4972
|
+
className: panel_module_css_default.scanProgressTrack,
|
|
4973
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4974
|
+
className: panel_module_css_default.scanProgressFill,
|
|
4975
|
+
style: { width: `${pct}%` }
|
|
4976
|
+
})
|
|
4977
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4978
|
+
style: {
|
|
4979
|
+
fontSize: 11,
|
|
4980
|
+
opacity: .75,
|
|
4981
|
+
minWidth: 32,
|
|
4982
|
+
textAlign: "right"
|
|
4983
|
+
},
|
|
4984
|
+
children: [pct, "%"]
|
|
4985
|
+
})]
|
|
4986
|
+
}),
|
|
4987
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4988
|
+
className: panel_module_css_default.hintLine,
|
|
4989
|
+
children: [
|
|
4990
|
+
formatBytes(repoResult.downloadedBytes),
|
|
4991
|
+
" / ",
|
|
4992
|
+
formatBytes(repoResult.totalBytes),
|
|
4993
|
+
speed !== "" ? ` · ${speed}` : "",
|
|
4994
|
+
" · ",
|
|
4995
|
+
repoResult.done,
|
|
4996
|
+
"/",
|
|
4997
|
+
repoResult.total,
|
|
4998
|
+
" 个技能"
|
|
4999
|
+
]
|
|
5000
|
+
}),
|
|
5001
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5002
|
+
className: panel_module_css_default.hintLine,
|
|
5003
|
+
style: { marginTop: 4 },
|
|
5004
|
+
children: [repoResult.current !== void 0 ? tt("repo.importingCurrent", {
|
|
5005
|
+
name: repoResult.current,
|
|
5006
|
+
done: repoResult.done + 1,
|
|
5007
|
+
total: repoResult.total
|
|
5008
|
+
}) : tt("repo.importing"), repoResult.currentFile !== void 0 ? ` · ${repoResult.currentFile}` : ""]
|
|
5009
|
+
}),
|
|
5010
|
+
repoResult.failed.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5011
|
+
className: panel_module_css_default.errorBanner,
|
|
5012
|
+
style: { marginTop: 6 },
|
|
5013
|
+
children: repoResult.failed.map((f) => `${f.name}: ${f.error}`).join("; ")
|
|
5014
|
+
}) : null
|
|
5015
|
+
]
|
|
5016
|
+
});
|
|
5017
|
+
})() : null
|
|
5018
|
+
] })
|
|
5019
|
+
] });
|
|
4698
5020
|
})() : null,
|
|
4699
5021
|
repoResult !== null && repoResult.status !== "running" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4700
5022
|
className: repoResult.status === "cancelled" ? panel_module_css_default.errorBanner + " " + panel_module_css_default.actionsTop : panel_module_css_default.formSuccess + " " + panel_module_css_default.actionsTop,
|
|
@@ -4801,6 +5123,7 @@ window.__ModuleLoader__.load({
|
|
|
4801
5123
|
const [tab, setTab] = (0, react.useState)("sources");
|
|
4802
5124
|
const [skillView, setSkillView] = (0, react.useState)("groups");
|
|
4803
5125
|
const [sourceFilter, setSourceFilter] = (0, react.useState)("all");
|
|
5126
|
+
const [invocationFilter, setInvocationFilter] = (0, react.useState)("all");
|
|
4804
5127
|
const [sortKey, setSortKey] = (0, react.useState)("name");
|
|
4805
5128
|
const [marketState, setMarketState] = (0, react.useState)({
|
|
4806
5129
|
status: "loading",
|
|
@@ -4831,8 +5154,9 @@ window.__ModuleLoader__.load({
|
|
|
4831
5154
|
const [newTagName, setNewTagName] = (0, react.useState)("");
|
|
4832
5155
|
const [tagBusy, setTagBusy] = (0, react.useState)(false);
|
|
4833
5156
|
const [editSearch, setEditSearch] = (0, react.useState)("");
|
|
4834
|
-
/** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project
|
|
5157
|
+
/** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project 树键)。技能总数 >80 时首次加载自动折叠 personal。 */
|
|
4835
5158
|
const [collapsedGroups, setCollapsedGroups] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
5159
|
+
const autoCollapsedPersonal = (0, react.useRef)(false);
|
|
4836
5160
|
/** 项目级三级树里已细分(按 .dsh/.agents)的项目键。 */
|
|
4837
5161
|
const [subdividedProjects, setSubdividedProjects] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
4838
5162
|
const [showLegend, setShowLegend] = (0, react.useState)(false);
|
|
@@ -4857,6 +5181,10 @@ window.__ModuleLoader__.load({
|
|
|
4857
5181
|
try {
|
|
4858
5182
|
const next = await api.catalog(workspace !== "" ? { cwd: workspace } : void 0);
|
|
4859
5183
|
setCatalog(next);
|
|
5184
|
+
if (!autoCollapsedPersonal.current && next.skills.length + next.disabled.length > 80) {
|
|
5185
|
+
autoCollapsedPersonal.current = true;
|
|
5186
|
+
setCollapsedGroups((previous) => new Set(previous).add("uncategorized-source"));
|
|
5187
|
+
}
|
|
4860
5188
|
setLoadError(null);
|
|
4861
5189
|
} catch (error) {
|
|
4862
5190
|
setLoadError(errorMessage(error));
|
|
@@ -5183,6 +5511,25 @@ window.__ModuleLoader__.load({
|
|
|
5183
5511
|
load,
|
|
5184
5512
|
loadSources
|
|
5185
5513
|
]);
|
|
5514
|
+
const [fixingPaths, setFixingPaths] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
5515
|
+
const fixDiagnostic = (0, react.useCallback)(async (path) => {
|
|
5516
|
+
setFixingPaths((previous) => new Set(previous).add(path));
|
|
5517
|
+
setLoadError(null);
|
|
5518
|
+
try {
|
|
5519
|
+
if (!window.confirm(tt("diag.fixConfirm", { path }))) return;
|
|
5520
|
+
await api.fixDiagnostic(path);
|
|
5521
|
+
await load();
|
|
5522
|
+
setSuccessBanner(tt("diag.fixed"));
|
|
5523
|
+
} catch (error) {
|
|
5524
|
+
setLoadError(errorMessage(error));
|
|
5525
|
+
} finally {
|
|
5526
|
+
setFixingPaths((previous) => {
|
|
5527
|
+
const next = new Set(previous);
|
|
5528
|
+
next.delete(path);
|
|
5529
|
+
return next;
|
|
5530
|
+
});
|
|
5531
|
+
}
|
|
5532
|
+
}, [api, load]);
|
|
5186
5533
|
/** 打开单个技能的删除确认(移入回收站,可恢复)。 */
|
|
5187
5534
|
const requestDeleteSkill = (0, react.useCallback)((name) => {
|
|
5188
5535
|
setDeleteSkillDialog(name);
|
|
@@ -5466,6 +5813,7 @@ window.__ModuleLoader__.load({
|
|
|
5466
5813
|
status: "ready",
|
|
5467
5814
|
data
|
|
5468
5815
|
});
|
|
5816
|
+
loadMarket();
|
|
5469
5817
|
} catch (error) {
|
|
5470
5818
|
setRepoDiscoverState({
|
|
5471
5819
|
status: "error",
|
|
@@ -5474,7 +5822,7 @@ window.__ModuleLoader__.load({
|
|
|
5474
5822
|
} finally {
|
|
5475
5823
|
setScanningRepo(null);
|
|
5476
5824
|
}
|
|
5477
|
-
}, [api]);
|
|
5825
|
+
}, [api, loadMarket]);
|
|
5478
5826
|
/** 确认分支选择:持久化 ref 后重新扫描。 */
|
|
5479
5827
|
const confirmBranchChoice = (0, react.useCallback)(async () => {
|
|
5480
5828
|
if (branchChoice === null) return;
|
|
@@ -5494,6 +5842,59 @@ window.__ModuleLoader__.load({
|
|
|
5494
5842
|
branchChoice,
|
|
5495
5843
|
scanRepo
|
|
5496
5844
|
]);
|
|
5845
|
+
/** 版本对话框:打开时拉 releases + branches,确认后定版并重扫。 */
|
|
5846
|
+
const [versionDialog, setVersionDialog] = (0, react.useState)(null);
|
|
5847
|
+
const [versionBusy, setVersionBusy] = (0, react.useState)(false);
|
|
5848
|
+
const openVersionDialog = (0, react.useCallback)(async (repo) => {
|
|
5849
|
+
const current = marketState.repos.find((item) => item.repo === repo)?.ref;
|
|
5850
|
+
setVersionDialog({
|
|
5851
|
+
repo,
|
|
5852
|
+
...current !== void 0 ? { current } : {},
|
|
5853
|
+
releases: [],
|
|
5854
|
+
branches: [],
|
|
5855
|
+
selected: current ?? "",
|
|
5856
|
+
custom: "",
|
|
5857
|
+
loading: true
|
|
5858
|
+
});
|
|
5859
|
+
setLoadError(null);
|
|
5860
|
+
try {
|
|
5861
|
+
const data = await api.marketSourceVersions(repo);
|
|
5862
|
+
setVersionDialog({
|
|
5863
|
+
repo,
|
|
5864
|
+
...data.current !== void 0 ? { current: data.current } : {},
|
|
5865
|
+
releases: data.releases,
|
|
5866
|
+
branches: data.branches,
|
|
5867
|
+
selected: data.current ?? data.releases[0] ?? data.branches[0] ?? "",
|
|
5868
|
+
custom: "",
|
|
5869
|
+
loading: false
|
|
5870
|
+
});
|
|
5871
|
+
} catch (error) {
|
|
5872
|
+
setLoadError(errorMessage(error));
|
|
5873
|
+
setVersionDialog(null);
|
|
5874
|
+
}
|
|
5875
|
+
}, [api, marketState]);
|
|
5876
|
+
const confirmVersionDialog = (0, react.useCallback)(async () => {
|
|
5877
|
+
if (versionDialog === null) return;
|
|
5878
|
+
const ref = versionDialog.custom.trim() !== "" ? versionDialog.custom.trim() : versionDialog.selected;
|
|
5879
|
+
if (ref === "") return;
|
|
5880
|
+
setVersionBusy(true);
|
|
5881
|
+
setLoadError(null);
|
|
5882
|
+
try {
|
|
5883
|
+
await api.setMarketSourceRef(versionDialog.repo, ref);
|
|
5884
|
+
setVersionDialog(null);
|
|
5885
|
+
await loadMarket();
|
|
5886
|
+
await scanRepo(versionDialog.repo);
|
|
5887
|
+
} catch (error) {
|
|
5888
|
+
setLoadError(errorMessage(error));
|
|
5889
|
+
} finally {
|
|
5890
|
+
setVersionBusy(false);
|
|
5891
|
+
}
|
|
5892
|
+
}, [
|
|
5893
|
+
api,
|
|
5894
|
+
versionDialog,
|
|
5895
|
+
loadMarket,
|
|
5896
|
+
scanRepo
|
|
5897
|
+
]);
|
|
5497
5898
|
/** Toggle one repo preview row. */
|
|
5498
5899
|
const toggleRepoSelected = (0, react.useCallback)((path, checked) => {
|
|
5499
5900
|
setRepoSelected((previous) => {
|
|
@@ -5776,7 +6177,18 @@ window.__ModuleLoader__.load({
|
|
|
5776
6177
|
const hasPrivate = skills.some((skill) => origins[skill.name] === void 0 && !isProjectSource(skill.source));
|
|
5777
6178
|
return [...repos, ...hasPrivate ? [PRIVATE_SOURCE] : []];
|
|
5778
6179
|
}, [catalog, origins]);
|
|
5779
|
-
const filtered = (0, react.useMemo)(() => (catalog?.skills ?? []).filter((skill) =>
|
|
6180
|
+
const filtered = (0, react.useMemo)(() => (catalog?.skills ?? []).filter((skill) => {
|
|
6181
|
+
if (invocationFilter === "model" && !skill.invocation.modelInvocable) return false;
|
|
6182
|
+
if (invocationFilter === "user" && !skill.invocation.userInvocable) return false;
|
|
6183
|
+
if (normalized.length === 0) return true;
|
|
6184
|
+
return skill.name.toLocaleLowerCase().includes(normalized) || skill.description.toLocaleLowerCase().includes(normalized) || skill.displayName?.toLocaleLowerCase().includes(normalized) || skill.shortDescription?.toLocaleLowerCase().includes(normalized);
|
|
6185
|
+
}), [
|
|
6186
|
+
catalog,
|
|
6187
|
+
normalized,
|
|
6188
|
+
invocationFilter
|
|
6189
|
+
]);
|
|
6190
|
+
/** Rows actually rendered with a shortened description (shortDescription in use). */
|
|
6191
|
+
const shortenedCount = (0, react.useMemo)(() => filtered.filter((skill) => skill.shortDescription !== void 0).length, [filtered]);
|
|
5780
6192
|
return {
|
|
5781
6193
|
catalog,
|
|
5782
6194
|
loading,
|
|
@@ -5806,6 +6218,7 @@ window.__ModuleLoader__.load({
|
|
|
5806
6218
|
tab,
|
|
5807
6219
|
skillView,
|
|
5808
6220
|
sourceFilter,
|
|
6221
|
+
invocationFilter,
|
|
5809
6222
|
sortKey,
|
|
5810
6223
|
marketState,
|
|
5811
6224
|
marketCheck,
|
|
@@ -5836,6 +6249,8 @@ window.__ModuleLoader__.load({
|
|
|
5836
6249
|
subdividedProjects,
|
|
5837
6250
|
showLegend,
|
|
5838
6251
|
editMode,
|
|
6252
|
+
versionDialog,
|
|
6253
|
+
versionBusy,
|
|
5839
6254
|
actionNames,
|
|
5840
6255
|
viewNames,
|
|
5841
6256
|
normalized,
|
|
@@ -5847,6 +6262,7 @@ window.__ModuleLoader__.load({
|
|
|
5847
6262
|
sortKey,
|
|
5848
6263
|
uses
|
|
5849
6264
|
]),
|
|
6265
|
+
shortenedCount,
|
|
5850
6266
|
setLoadError,
|
|
5851
6267
|
setSuccessBanner,
|
|
5852
6268
|
setSearch,
|
|
@@ -5861,6 +6277,7 @@ window.__ModuleLoader__.load({
|
|
|
5861
6277
|
setTab,
|
|
5862
6278
|
setSkillView,
|
|
5863
6279
|
setSourceFilter,
|
|
6280
|
+
setInvocationFilter,
|
|
5864
6281
|
setSortKey,
|
|
5865
6282
|
setBranchChoice,
|
|
5866
6283
|
setMarketSyncDialog,
|
|
@@ -5878,6 +6295,7 @@ window.__ModuleLoader__.load({
|
|
|
5878
6295
|
setEditSearch,
|
|
5879
6296
|
setShowLegend,
|
|
5880
6297
|
setEditMode,
|
|
6298
|
+
setVersionDialog,
|
|
5881
6299
|
toggleGroupCollapse,
|
|
5882
6300
|
toggleSubdivide,
|
|
5883
6301
|
checkUpdate,
|
|
@@ -5894,6 +6312,15 @@ window.__ModuleLoader__.load({
|
|
|
5894
6312
|
requestDelete,
|
|
5895
6313
|
restoreTrash,
|
|
5896
6314
|
clearTrash,
|
|
6315
|
+
fixingPaths,
|
|
6316
|
+
fixDiagnostic,
|
|
6317
|
+
clearListFilters: (0, react.useCallback)(() => {
|
|
6318
|
+
setSearch("");
|
|
6319
|
+
setSourceFilter("all");
|
|
6320
|
+
setInvocationFilter("all");
|
|
6321
|
+
}, []),
|
|
6322
|
+
openVersionDialog,
|
|
6323
|
+
confirmVersionDialog,
|
|
5897
6324
|
requestDeleteSkill,
|
|
5898
6325
|
runDeleteSkill,
|
|
5899
6326
|
requestDeleteGroup,
|
|
@@ -5940,25 +6367,35 @@ window.__ModuleLoader__.load({
|
|
|
5940
6367
|
/** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */
|
|
5941
6368
|
const [workspaceDraft, setWorkspaceDraft] = (0, react.useState)("");
|
|
5942
6369
|
const { catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc, formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search, workspace, setWorkspace, sourcesState, tagBusy, busyNames, normalized, origins, sourceOptions, filtered, conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog, syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource, showLegend, editMode, setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab, setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog, setDeleteGroupDialog, setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch, setShowLegend, setEditMode, checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill, runDeleteGroup, runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled } = hub;
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
6370
|
+
const { shortenedCount, fixingPaths, clearListFilters } = hub;
|
|
6371
|
+
if (detail !== null) {
|
|
6372
|
+
const disabledRecord = catalog?.disabled.find((record) => record.name === detail.name);
|
|
6373
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkillDetailView, {
|
|
6374
|
+
detail,
|
|
6375
|
+
hubConfig,
|
|
6376
|
+
uses,
|
|
6377
|
+
groupsState,
|
|
6378
|
+
sourcesState,
|
|
6379
|
+
sourceCheck,
|
|
6380
|
+
checkingSource,
|
|
6381
|
+
syncingSource,
|
|
6382
|
+
loading: detailLoading,
|
|
6383
|
+
disabled: disabledRecord !== void 0,
|
|
6384
|
+
onEnable: disabledRecord !== void 0 ? () => {
|
|
6385
|
+
enableDisabled(disabledRecord).then(() => {
|
|
6386
|
+
setDetail(null);
|
|
6387
|
+
});
|
|
6388
|
+
} : void 0,
|
|
6389
|
+
onBack: () => {
|
|
6390
|
+
setDetail(null);
|
|
6391
|
+
},
|
|
6392
|
+
onCheck: (repo) => {
|
|
6393
|
+
checkSources(repo);
|
|
6394
|
+
},
|
|
6395
|
+
onSync: requestSync,
|
|
6396
|
+
onFollowDelete: requestDelete
|
|
6397
|
+
});
|
|
6398
|
+
}
|
|
5962
6399
|
if (editingTag !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagEditorView, {
|
|
5963
6400
|
tag: editingTag,
|
|
5964
6401
|
editName,
|
|
@@ -6033,6 +6470,20 @@ window.__ModuleLoader__.load({
|
|
|
6033
6470
|
className: panel_module_css_default.hint,
|
|
6034
6471
|
children: tt("panel.incomplete")
|
|
6035
6472
|
}) : null,
|
|
6473
|
+
catalog !== null && (catalog.duplicateNames?.length ?? 0) > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6474
|
+
type: "button",
|
|
6475
|
+
className: panel_module_css_default.opBtn,
|
|
6476
|
+
title: tt("row.duplicateHint"),
|
|
6477
|
+
onClick: () => {
|
|
6478
|
+
clearListFilters();
|
|
6479
|
+
},
|
|
6480
|
+
children: [
|
|
6481
|
+
"⚠ ",
|
|
6482
|
+
tt("row.duplicate"),
|
|
6483
|
+
"×",
|
|
6484
|
+
(catalog.duplicateNames ?? []).length
|
|
6485
|
+
]
|
|
6486
|
+
}) : null,
|
|
6036
6487
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6037
6488
|
className: panel_module_css_default.actions,
|
|
6038
6489
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -6323,6 +6774,27 @@ window.__ModuleLoader__.load({
|
|
|
6323
6774
|
})
|
|
6324
6775
|
]
|
|
6325
6776
|
}),
|
|
6777
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
6778
|
+
className: panel_module_css_default.select,
|
|
6779
|
+
value: hub.invocationFilter,
|
|
6780
|
+
onChange: (event) => {
|
|
6781
|
+
hub.setInvocationFilter(event.target.value);
|
|
6782
|
+
},
|
|
6783
|
+
children: [
|
|
6784
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6785
|
+
value: "all",
|
|
6786
|
+
children: tt("filter.invocationAll")
|
|
6787
|
+
}),
|
|
6788
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6789
|
+
value: "model",
|
|
6790
|
+
children: tt("filter.modelOnly")
|
|
6791
|
+
}),
|
|
6792
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
6793
|
+
value: "user",
|
|
6794
|
+
children: tt("filter.userOnly")
|
|
6795
|
+
})
|
|
6796
|
+
]
|
|
6797
|
+
}),
|
|
6326
6798
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6327
6799
|
className: panel_module_css_default.search,
|
|
6328
6800
|
value: search,
|
|
@@ -6340,6 +6812,23 @@ window.__ModuleLoader__.load({
|
|
|
6340
6812
|
})
|
|
6341
6813
|
]
|
|
6342
6814
|
}),
|
|
6815
|
+
catalog !== null && (filtered.length !== catalog.skills.length || hub.invocationFilter !== "all" || sourceFilter !== "all") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6816
|
+
className: panel_module_css_default.hintLine,
|
|
6817
|
+
style: {
|
|
6818
|
+
margin: "2px 2px 0",
|
|
6819
|
+
display: "flex",
|
|
6820
|
+
gap: 8,
|
|
6821
|
+
flexWrap: "wrap"
|
|
6822
|
+
},
|
|
6823
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("filter.showing", {
|
|
6824
|
+
shown: filtered.length,
|
|
6825
|
+
total: catalog.skills.length,
|
|
6826
|
+
filtered: hub.invocationFilter !== "all" || sourceFilter !== "all" ? tt("filter.filteredSuffix") : ""
|
|
6827
|
+
}) }), shortenedCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6828
|
+
title: tt("filter.shortened", { count: shortenedCount }),
|
|
6829
|
+
children: tt("filter.shortened", { count: shortenedCount })
|
|
6830
|
+
}) : null]
|
|
6831
|
+
}) : null,
|
|
6343
6832
|
filtered.length === 0 && search.trim() !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6344
6833
|
className: panel_module_css_default.empty,
|
|
6345
6834
|
children: tt("panel.empty")
|
|
@@ -6394,13 +6883,36 @@ window.__ModuleLoader__.load({
|
|
|
6394
6883
|
children: tt("panel.diagnostics")
|
|
6395
6884
|
}), catalog.diagnostics.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6396
6885
|
className: panel_module_css_default.diagRow,
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6886
|
+
style: {
|
|
6887
|
+
display: "flex",
|
|
6888
|
+
alignItems: "flex-start",
|
|
6889
|
+
gap: 10
|
|
6890
|
+
},
|
|
6891
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6892
|
+
style: {
|
|
6893
|
+
flex: 1,
|
|
6894
|
+
minWidth: 0
|
|
6895
|
+
},
|
|
6896
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6897
|
+
className: panel_module_css_default.diagPath,
|
|
6898
|
+
children: entry.path
|
|
6899
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6900
|
+
className: panel_module_css_default.diagReason,
|
|
6901
|
+
children: entry.reason
|
|
6902
|
+
})]
|
|
6903
|
+
}), entry.fixable === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6904
|
+
type: "button",
|
|
6905
|
+
className: panel_module_css_default.opBtn,
|
|
6906
|
+
disabled: fixingPaths.has(entry.path),
|
|
6907
|
+
onClick: () => {
|
|
6908
|
+
hub.fixDiagnostic(entry.path);
|
|
6909
|
+
},
|
|
6910
|
+
style: {
|
|
6911
|
+
flex: "none",
|
|
6912
|
+
alignSelf: "center"
|
|
6913
|
+
},
|
|
6914
|
+
children: fixingPaths.has(entry.path) ? tt("diag.fixing") : tt("diag.fix")
|
|
6915
|
+
}) : null]
|
|
6404
6916
|
}, entry.path))]
|
|
6405
6917
|
}) : null
|
|
6406
6918
|
] }) : null,
|
|
@@ -6447,6 +6959,28 @@ window.__ModuleLoader__.load({
|
|
|
6447
6959
|
confirmBranchChoice();
|
|
6448
6960
|
}
|
|
6449
6961
|
}) : null,
|
|
6962
|
+
hub.versionDialog !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VersionChoiceDialog, {
|
|
6963
|
+
choice: hub.versionDialog,
|
|
6964
|
+
busy: hub.versionBusy,
|
|
6965
|
+
onSelect: (selected) => {
|
|
6966
|
+
hub.setVersionDialog({
|
|
6967
|
+
...hub.versionDialog,
|
|
6968
|
+
selected
|
|
6969
|
+
});
|
|
6970
|
+
},
|
|
6971
|
+
onCustom: (custom) => {
|
|
6972
|
+
hub.setVersionDialog({
|
|
6973
|
+
...hub.versionDialog,
|
|
6974
|
+
custom
|
|
6975
|
+
});
|
|
6976
|
+
},
|
|
6977
|
+
onCancel: () => {
|
|
6978
|
+
hub.setVersionDialog(null);
|
|
6979
|
+
},
|
|
6980
|
+
onConfirm: () => {
|
|
6981
|
+
hub.confirmVersionDialog();
|
|
6982
|
+
}
|
|
6983
|
+
}) : null,
|
|
6450
6984
|
marketSyncDialog !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MarketSyncDialog, {
|
|
6451
6985
|
dialog: marketSyncDialog,
|
|
6452
6986
|
busy: syncBusy,
|