dsh-skill-hub 0.3.26 → 0.3.28
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/CONTRIBUTING.md +1 -1
- package/README.md +11 -3
- package/README.zh.md +11 -3
- package/lib/client.js +310 -39
- package/lib/client.js.map +1 -1
- package/lib/index.js +790 -15
- package/lib/types/client/api.d.ts +8 -1
- package/lib/types/client/locales/common.d.ts +4 -0
- package/lib/types/client/locales/market.d.ts +10 -0
- package/lib/types/client/locales/sources.d.ts +3 -0
- package/lib/types/client/locales.d.ts +17 -0
- package/lib/types/client/panel/ForeignImportDialog.d.ts +15 -0
- package/lib/types/client/panel/PanelDialogs.d.ts +2 -0
- package/lib/types/client/panel/dialogs.d.ts +11 -1
- package/lib/types/client/panel/useSkillHub.d.ts +1 -0
- package/lib/types/protocol/api.d.ts +2 -0
- package/lib/types/protocol/catalog.d.ts +39 -1
- package/lib/types/protocol/foreign.d.ts +51 -0
- package/lib/types/protocol/sources.d.ts +13 -0
- package/lib/types/protocol.d.ts +3 -1
- package/lib/types/repo/install.d.ts +4 -0
- package/lib/types/routes/deps.d.ts +11 -0
- package/lib/types/routes/foreign.d.ts +10 -0
- package/lib/types/routes/helpers.d.ts +1 -1
- package/lib/types/skillfs/audit.d.ts +58 -0
- package/lib/types/skillfs/foreign.d.ts +51 -0
- package/lib/types/skillfs/hash.d.ts +24 -0
- package/lib/types/skillfs.d.ts +2 -0
- package/lib/types/store/store.d.ts +6 -0
- package/package.json +23 -21
- package/src/client/api.ts +14 -0
- package/src/client/locales/common.ts +8 -0
- package/src/client/locales/market.ts +20 -0
- package/src/client/locales/sources.ts +6 -0
- package/src/client/panel/ForeignImportDialog.tsx +130 -0
- package/src/client/panel/PanelDialogs.tsx +4 -1
- package/src/client/panel/SkillHubPanel.tsx +34 -4
- package/src/client/panel/SourceStatusBadge.tsx +23 -13
- package/src/client/panel/dialogs.tsx +14 -3
- package/src/client/panel/panel.module.css +6 -0
- package/src/client/panel/useSkillHub.ts +1 -1
- package/src/index.ts +2 -2
- package/src/protocol/api.ts +2 -0
- package/src/protocol/catalog.ts +56 -0
- package/src/protocol/foreign.ts +47 -0
- package/src/protocol/sources.ts +13 -0
- package/src/protocol.test.ts +59 -0
- package/src/protocol.ts +3 -0
- package/src/repo/install.ts +34 -0
- package/src/repo.test.ts +55 -0
- package/src/routes/catalog-data.ts +2 -0
- package/src/routes/deps.ts +15 -0
- package/src/routes/foreign.ts +127 -0
- package/src/routes/helpers.ts +1 -0
- package/src/routes/repo-import.ts +4 -1
- package/src/routes/sources.ts +53 -3
- package/src/routes.test.ts +162 -3
- package/src/routes.ts +2 -0
- package/src/skillfs/audit.test.ts +182 -0
- package/src/skillfs/audit.ts +229 -0
- package/src/skillfs/foreign.test.ts +121 -0
- package/src/skillfs/foreign.ts +198 -0
- package/src/skillfs/hash.test.ts +129 -0
- package/src/skillfs/hash.ts +112 -0
- package/src/skillfs/scan.ts +17 -0
- package/src/skillfs.test.ts +37 -0
- package/src/skillfs.ts +2 -0
- package/src/store/migrate.ts +7 -1
- package/src/store/store.ts +36 -3
- package/src/store.test.ts +24 -0
package/lib/client.js
CHANGED
|
@@ -49,7 +49,9 @@ window.__ModuleLoader__.load({
|
|
|
49
49
|
sourceTrashClear: "/api/skill-hub/sources/trash/clear",
|
|
50
50
|
diagnosticFix: "/api/skill-hub/diagnostic/fix",
|
|
51
51
|
marketSourceVersions: "/api/skill-hub/market/source/versions",
|
|
52
|
-
marketStats: "/api/skill-hub/market/stats"
|
|
52
|
+
marketStats: "/api/skill-hub/market/stats",
|
|
53
|
+
foreign: "/api/skill-hub/foreign",
|
|
54
|
+
foreignImport: "/api/skill-hub/foreign/import"
|
|
53
55
|
};
|
|
54
56
|
//#endregion
|
|
55
57
|
//#region src/protocol/config.ts
|
|
@@ -287,6 +289,15 @@ window.__ModuleLoader__.load({
|
|
|
287
289
|
sources() {
|
|
288
290
|
return this.get(SKILL_HUB_API.sources);
|
|
289
291
|
}
|
|
292
|
+
/** 列出其他 agent 用户级技能目录里的可收编技能(只读扫描)。 */
|
|
293
|
+
listForeignSkills() {
|
|
294
|
+
return this.get(SKILL_HUB_API.foreign);
|
|
295
|
+
}
|
|
296
|
+
/** 收编所选外部技能到 ~/.dsh/skills。 */
|
|
297
|
+
importForeignSkills(items) {
|
|
298
|
+
const payload = { items };
|
|
299
|
+
return this.post(SKILL_HUB_API.foreignImport, payload);
|
|
300
|
+
}
|
|
290
301
|
/** 检查指定(或全部)来源的上游更新。 */
|
|
291
302
|
checkSources(repo) {
|
|
292
303
|
const payload = repo !== void 0 ? { repo } : {};
|
|
@@ -343,6 +354,10 @@ window.__ModuleLoader__.load({
|
|
|
343
354
|
"legend.hint": "每个技能最多一个圆点;无圆点 = 不可被调用。",
|
|
344
355
|
"panel.disabled": "已禁用",
|
|
345
356
|
"panel.diagnostics": "发现诊断",
|
|
357
|
+
"panel.auditBadge": "审计",
|
|
358
|
+
"panel.announcement": "公告预算 {chars} 字符 ≈ {tokens} tokens · {skills} 个技能",
|
|
359
|
+
"panel.announcementOver": "超出建议上限 {budget} 字符,排在后面的技能可能不触发",
|
|
360
|
+
"panel.announcementHint": "技能目录的第一层(name + description)常驻在 system prompt 里。建议不超 {budget} 字符 —— 超出后客户端会截断尾部条目,表现为「装了却不触发」。",
|
|
346
361
|
"panel.empty": "没有匹配的技能。",
|
|
347
362
|
"panel.emptyAll": "本地还没有技能。点击「新建技能」创建第一个。",
|
|
348
363
|
"panel.loading": "读取中…",
|
|
@@ -391,6 +406,10 @@ window.__ModuleLoader__.load({
|
|
|
391
406
|
"legend.hint": "At most one dot per skill; no dot = not invocable.",
|
|
392
407
|
"panel.disabled": "Disabled",
|
|
393
408
|
"panel.diagnostics": "Discovery diagnostics",
|
|
409
|
+
"panel.auditBadge": "audit",
|
|
410
|
+
"panel.announcement": "Announcement budget: {chars} chars ≈ {tokens} tokens · {skills} skills",
|
|
411
|
+
"panel.announcementOver": "over the suggested {budget}-char cap — later skills may stop triggering",
|
|
412
|
+
"panel.announcementHint": "The first progressive-disclosure layer (name + description) sits in the system prompt. Stay under {budget} chars: past it, clients truncate the tail and skills silently stop triggering.",
|
|
394
413
|
"panel.empty": "No matching skills.",
|
|
395
414
|
"panel.emptyAll": "No skills installed yet. Create the first one.",
|
|
396
415
|
"panel.loading": "Loading…",
|
|
@@ -534,7 +553,17 @@ window.__ModuleLoader__.load({
|
|
|
534
553
|
"repo.root.self": "仓库根",
|
|
535
554
|
"repo.root.skills": "skills",
|
|
536
555
|
"repo.root.designTemplates": "design-templates",
|
|
537
|
-
"repo.root.generic": "{root}"
|
|
556
|
+
"repo.root.generic": "{root}",
|
|
557
|
+
"foreign.open": "从其他 Agent 导入",
|
|
558
|
+
"foreign.title": "从其他 Agent 导入",
|
|
559
|
+
"foreign.text": "读取 Claude Code / Codex / Cursor 等工具的用户级技能目录(只读),把所选技能复制到 ~/.dsh/skills。原目录不受影响。",
|
|
560
|
+
"foreign.empty": "没有在这些工具的技能目录里发现技能。",
|
|
561
|
+
"foreign.exists": "已存在",
|
|
562
|
+
"foreign.import": "导入所选({count})",
|
|
563
|
+
"foreign.importing": "导入中…",
|
|
564
|
+
"foreign.skipped": "{count} 个因同名已存在被跳过。",
|
|
565
|
+
"foreign.importedBanner": "已导入 {count} 个技能。",
|
|
566
|
+
"foreign.importedReplacedBanner": "已导入 {count} 个技能,另有 {replaced} 个同名占位被移入回收站(可恢复)。"
|
|
538
567
|
};
|
|
539
568
|
const enMarket = {
|
|
540
569
|
"market.syncHint": "Sync to the latest upstream and report local skills that can update",
|
|
@@ -615,7 +644,17 @@ window.__ModuleLoader__.load({
|
|
|
615
644
|
"repo.root.self": "Repo root",
|
|
616
645
|
"repo.root.skills": "Skills",
|
|
617
646
|
"repo.root.designTemplates": "Templates",
|
|
618
|
-
"repo.root.generic": "{root}"
|
|
647
|
+
"repo.root.generic": "{root}",
|
|
648
|
+
"foreign.open": "Import from another agent",
|
|
649
|
+
"foreign.title": "Import from another agent",
|
|
650
|
+
"foreign.text": "Reads the user-level skill folders of Claude Code / Codex / Cursor and friends (read-only) and copies the selected skills into ~/.dsh/skills. The originals are left untouched.",
|
|
651
|
+
"foreign.empty": "No skills found in those tool folders.",
|
|
652
|
+
"foreign.exists": "exists",
|
|
653
|
+
"foreign.import": "Import {count}",
|
|
654
|
+
"foreign.importing": "Importing…",
|
|
655
|
+
"foreign.skipped": "{count} skipped because the name already exists.",
|
|
656
|
+
"foreign.importedBanner": "Imported {count} skill(s).",
|
|
657
|
+
"foreign.importedReplacedBanner": "Imported {count} skill(s); {replaced} same-name placeholder(s) moved to trash (restorable)."
|
|
619
658
|
};
|
|
620
659
|
//#endregion
|
|
621
660
|
//#region src/client/locales/settings.ts
|
|
@@ -834,6 +873,9 @@ window.__ModuleLoader__.load({
|
|
|
834
873
|
"source.checking": "检查中…",
|
|
835
874
|
"source.upToDate": "已是最新",
|
|
836
875
|
"source.updated": "有更新 {count} 个",
|
|
876
|
+
"source.localModified": "本地改动 {count} 个",
|
|
877
|
+
"source.localModifiedBadge": "本地已改",
|
|
878
|
+
"source.localModifiedHint": "这些技能的磁盘内容与导入/同步时不一致(你自己改过)。同步会覆盖它们。",
|
|
837
879
|
"source.deleted": "上游已删除 {count} 个",
|
|
838
880
|
"source.error": "检查失败",
|
|
839
881
|
"source.throttled": "刚刚检查过",
|
|
@@ -867,6 +909,9 @@ window.__ModuleLoader__.load({
|
|
|
867
909
|
"source.checking": "Checking…",
|
|
868
910
|
"source.upToDate": "Up to date",
|
|
869
911
|
"source.updated": "{count} updates",
|
|
912
|
+
"source.localModified": "{count} edited locally",
|
|
913
|
+
"source.localModifiedBadge": "edited",
|
|
914
|
+
"source.localModifiedHint": "These skills no longer match what was imported or synced — you changed them on disk. Syncing overwrites them.",
|
|
870
915
|
"source.deleted": "{count} deleted upstream",
|
|
871
916
|
"source.error": "Check failed",
|
|
872
917
|
"source.throttled": "Checked recently",
|
|
@@ -2809,7 +2854,7 @@ window.__ModuleLoader__.load({
|
|
|
2809
2854
|
}
|
|
2810
2855
|
//#endregion
|
|
2811
2856
|
//#region \0dsh-css:/Users/huanyi/Documents/personal/tools/dsh-skill-hub/src/client/panel/panel.module.css.mjs
|
|
2812
|
-
const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;--hub-model:#2f81f7;--hub-user:#3fb950;--hub-accent:var(--dsw-alias-state-business-primary,#2f81f7);--hub-text:var(--dsw-alias-label-primary,currentColor);--hub-text-2:var(--dsw-alias-label-secondary,#61666b);--hub-text-3:var(--dsw-alias-label-tertiary,#81858c);--hub-text-4:var(--dsw-alias-label-caption,#adb2b8);--hub-surface:var(--dsw-alias-bg-module-platform,#8080800f);--hub-hover:var(--dsw-alias-interactive-bg-hover,#80808014);--hub-active:var(--dsw-alias-interactive-bg-active,#80808029);--hub-border:var(--dsw-alias-border-l2,#80808021);--hub-border-2:var(--dsw-alias-border-l3,#80808033);--hub-danger:var(--dsw-alias-state-error-primary,#d1242f);--hub-success:var(--dsw-alias-state-success-primary,#3fb950);--hub-warn:var(--dsw-alias-state-warn-primary,#d29922);--hub-on-accent:var(--dsw-alias-label-primary-foreground,#fff);--hub-skeleton:var(--dsw-alias-bg-skeleton,#8080801a);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{color:var(--hub-text-3);font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:var(--hub-hover);border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:var(--hub-text-2);cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{color:var(--hub-text)}._6VtqdG_segBtnActive{background:var(--hub-active);opacity:1;font-weight:600}._6VtqdG_search{background:var(--hub-surface);width:100%;color:inherit;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:var(--hub-active)}._6VtqdG_section{background:var(--hub-surface);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{color:var(--hub-text);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{background:var(--hub-hover);color:inherit;cursor:pointer;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:var(--hub-active)}._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:var(--hub-hover)}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-accent);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid var(--hub-border)}._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{color:var(--hub-text-3);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{border:.5px solid var(--hub-border-2);color:var(--hub-text-2);white-space:nowrap;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{border:1px solid var(--hub-border-2);background:var(--dsw-alias-bg-module-platform,#8080804d);cursor:pointer;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:var(--dsw-alias-state-business-primary,#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{color:var(--hub-text-3);text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{border-left:3px solid var(--hub-warn);background:#d299220f;padding:9px 14px;font-size:12px}._6VtqdG_diagPath{color:var(--hub-text-2);word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{color:var(--hub-text-3);margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:var(--hub-danger);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:var(--hub-success);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{background:var(--hub-hover);color:inherit;cursor:pointer;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:var(--hub-active)}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{color:var(--hub-text-3);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:var(--hub-surface);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:var(--hub-surface);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{color:var(--hub-text-3);font-size:12px}._6VtqdG_input,._6VtqdG_select{background:var(--hub-surface);color:inherit;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:var(--hub-active)}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;background:var(--hub-hover);color:inherit;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:var(--hub-active)}._6VtqdG_primary{background:var(--hub-accent);color:var(--hub-on-accent)}._6VtqdG_primary:hover{background:var(--hub-accent);opacity:.92}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{background:var(--hub-danger);color:var(--hub-on-accent)}._6VtqdG_danger:hover{background:var(--hub-danger);opacity:.92}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:var(--hub-danger)}._6VtqdG_formSuccess{color:var(--hub-success)}._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{color:var(--hub-text-3);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{color:var(--hub-text-3);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{background:var(--hub-hover);opacity:.72;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{color:var(--hub-text-3);white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{color:var(--hub-text-4);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{background:var(--hub-hover);width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;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:var(--hub-active)}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:var(--hub-warn);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{color:var(--hub-text-4);white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773;background:color-mix(in srgb, var(--hub-accent) 45%, transparent)}._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{border:.5px solid var(--hub-border-2);opacity:.8;white-space:nowrap;background:var(--hub-hover);border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:var(--hub-success);background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:var(--hub-warn);background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:var(--hub-danger);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:var(--hub-danger);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:var(--hub-surface);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-alias-bg-layer-1,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-alias-label-primary,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{color:var(--hub-text-3);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{color:var(--hub-text-3);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 var(--dsw-alias-border-l1,#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-accent);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{border:.5px solid var(--hub-border-2);background:var(--hub-surface);border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:var(--hub-surface);border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-accent);height:100%;transition:width .2s}._6VtqdG_filterPanel{background:var(--hub-surface);border-radius:10px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 12px;display:flex}._6VtqdG_filterField{align-items:center;gap:6px;display:inline-flex}._6VtqdG_filterField ._6VtqdG_formLabel{margin:0}._6VtqdG_filterField ._6VtqdG_select{max-width:150px}._6VtqdG_listTools{justify-content:flex-end;align-items:center;gap:8px;padding:0 2px;display:flex}._6VtqdG_opBtn:focus-visible,._6VtqdG_button:focus-visible,._6VtqdG_segBtn:focus-visible,._6VtqdG_disclosure:focus-visible,._6VtqdG_switch:focus-visible,._6VtqdG_legendToggle:focus-visible,._6VtqdG_back:focus-visible,._6VtqdG_statusWrap:focus-visible,._6VtqdG_input:focus-visible,._6VtqdG_select:focus-visible,._6VtqdG_search:focus-visible,._6VtqdG_sourceLink:focus-visible{outline:2px solid var(--hub-accent);outline-offset:2px}._6VtqdG_opBtn{padding:4px 12px}._6VtqdG_segBtn{padding:6px 13px}._6VtqdG_iconBtn,._6VtqdG_legendToggle{width:28px;height:28px}._6VtqdG_dragHandle{opacity:.45;width:16px}._6VtqdG_dragHandle:hover{opacity:1}._6VtqdG_skeleton{background:var(--hub-surface);border-radius:12px;flex-direction:column;gap:8px;padding:14px;display:flex}._6VtqdG_skeletonRow{background:var(--hub-skeleton);border-radius:7px;height:14px;animation:1.4s ease-in-out infinite _6VtqdG_hubPulse}._6VtqdG_skeletonRow:nth-child(2){width:82%}._6VtqdG_skeletonRow:nth-child(3){width:64%}@keyframes _6VtqdG_hubPulse{0%,to{opacity:.55}50%{opacity:1}}@media (prefers-reduced-motion:reduce){._6VtqdG_panel *,._6VtqdG_panel :before,._6VtqdG_panel :after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}";
|
|
2857
|
+
const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;--hub-model:#2f81f7;--hub-user:#3fb950;--hub-accent:var(--dsw-alias-state-business-primary,#2f81f7);--hub-text:var(--dsw-alias-label-primary,currentColor);--hub-text-2:var(--dsw-alias-label-secondary,#61666b);--hub-text-3:var(--dsw-alias-label-tertiary,#81858c);--hub-text-4:var(--dsw-alias-label-caption,#adb2b8);--hub-surface:var(--dsw-alias-bg-module-platform,#8080800f);--hub-hover:var(--dsw-alias-interactive-bg-hover,#80808014);--hub-active:var(--dsw-alias-interactive-bg-active,#80808029);--hub-border:var(--dsw-alias-border-l2,#80808021);--hub-border-2:var(--dsw-alias-border-l3,#80808033);--hub-danger:var(--dsw-alias-state-error-primary,#d1242f);--hub-success:var(--dsw-alias-state-success-primary,#3fb950);--hub-warn:var(--dsw-alias-state-warn-primary,#d29922);--hub-on-accent:var(--dsw-alias-label-primary-foreground,#fff);--hub-skeleton:var(--dsw-alias-bg-skeleton,#8080801a);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{color:var(--hub-text-3);font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:var(--hub-hover);border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:var(--hub-text-2);cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{color:var(--hub-text)}._6VtqdG_segBtnActive{background:var(--hub-active);opacity:1;font-weight:600}._6VtqdG_search{background:var(--hub-surface);width:100%;color:inherit;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:var(--hub-active)}._6VtqdG_section{background:var(--hub-surface);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{color:var(--hub-text);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{background:var(--hub-hover);color:inherit;cursor:pointer;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:var(--hub-active)}._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:var(--hub-hover)}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-accent);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid var(--hub-border)}._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{color:var(--hub-text-3);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{border:.5px solid var(--hub-border-2);color:var(--hub-text-2);white-space:nowrap;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{border:1px solid var(--hub-border-2);background:var(--dsw-alias-bg-module-platform,#8080804d);cursor:pointer;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:var(--dsw-alias-state-business-primary,#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{color:var(--hub-text-3);text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{border-left:3px solid var(--hub-warn);background:#d299220f;padding:9px 14px;font-size:12px}._6VtqdG_diagRowBlock{border-left-color:var(--hub-danger);background:#d1242f0f}._6VtqdG_auditBadge{color:var(--hub-danger);vertical-align:1px;background:#d1242f1f;border-radius:4px;margin-right:6px;padding:0 5px;font-size:11px;font-weight:700;display:inline-block}._6VtqdG_diagPath{color:var(--hub-text-2);word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{color:var(--hub-text-3);margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:var(--hub-danger);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:var(--hub-success);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{background:var(--hub-hover);color:inherit;cursor:pointer;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:var(--hub-active)}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{color:var(--hub-text-3);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:var(--hub-surface);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:var(--hub-surface);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{color:var(--hub-text-3);font-size:12px}._6VtqdG_input,._6VtqdG_select{background:var(--hub-surface);color:inherit;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:var(--hub-active)}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;background:var(--hub-hover);color:inherit;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:var(--hub-active)}._6VtqdG_primary{background:var(--hub-accent);color:var(--hub-on-accent)}._6VtqdG_primary:hover{background:var(--hub-accent);opacity:.92}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{background:var(--hub-danger);color:var(--hub-on-accent)}._6VtqdG_danger:hover{background:var(--hub-danger);opacity:.92}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:var(--hub-danger)}._6VtqdG_formSuccess{color:var(--hub-success)}._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{color:var(--hub-text-3);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{color:var(--hub-text-3);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{background:var(--hub-hover);opacity:.72;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{color:var(--hub-text-3);white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{color:var(--hub-text-4);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{background:var(--hub-hover);width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;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:var(--hub-active)}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:var(--hub-warn);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{color:var(--hub-text-4);white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773;background:color-mix(in srgb, var(--hub-accent) 45%, transparent)}._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{border:.5px solid var(--hub-border-2);opacity:.8;white-space:nowrap;background:var(--hub-hover);border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:var(--hub-success);background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:var(--hub-warn);background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:var(--hub-danger);background:#d1242f14;border-color:currentColor}._6VtqdG_statusLocal{color:var(--hub-accent);background:#2f81f714;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:var(--hub-danger);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:var(--hub-surface);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-alias-bg-layer-1,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-alias-label-primary,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{color:var(--hub-text-3);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{color:var(--hub-text-3);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 var(--dsw-alias-border-l1,#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-accent);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{border:.5px solid var(--hub-border-2);background:var(--hub-surface);border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:var(--hub-surface);border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-accent);height:100%;transition:width .2s}._6VtqdG_filterPanel{background:var(--hub-surface);border-radius:10px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 12px;display:flex}._6VtqdG_filterField{align-items:center;gap:6px;display:inline-flex}._6VtqdG_filterField ._6VtqdG_formLabel{margin:0}._6VtqdG_filterField ._6VtqdG_select{max-width:150px}._6VtqdG_listTools{justify-content:flex-end;align-items:center;gap:8px;padding:0 2px;display:flex}._6VtqdG_opBtn:focus-visible,._6VtqdG_button:focus-visible,._6VtqdG_segBtn:focus-visible,._6VtqdG_disclosure:focus-visible,._6VtqdG_switch:focus-visible,._6VtqdG_legendToggle:focus-visible,._6VtqdG_back:focus-visible,._6VtqdG_statusWrap:focus-visible,._6VtqdG_input:focus-visible,._6VtqdG_select:focus-visible,._6VtqdG_search:focus-visible,._6VtqdG_sourceLink:focus-visible{outline:2px solid var(--hub-accent);outline-offset:2px}._6VtqdG_opBtn{padding:4px 12px}._6VtqdG_segBtn{padding:6px 13px}._6VtqdG_iconBtn,._6VtqdG_legendToggle{width:28px;height:28px}._6VtqdG_dragHandle{opacity:.45;width:16px}._6VtqdG_dragHandle:hover{opacity:1}._6VtqdG_skeleton{background:var(--hub-surface);border-radius:12px;flex-direction:column;gap:8px;padding:14px;display:flex}._6VtqdG_skeletonRow{background:var(--hub-skeleton);border-radius:7px;height:14px;animation:1.4s ease-in-out infinite _6VtqdG_hubPulse}._6VtqdG_skeletonRow:nth-child(2){width:82%}._6VtqdG_skeletonRow:nth-child(3){width:64%}@keyframes _6VtqdG_hubPulse{0%,to{opacity:.55}50%{opacity:1}}@media (prefers-reduced-motion:reduce){._6VtqdG_panel *,._6VtqdG_panel :before,._6VtqdG_panel :after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}";
|
|
2813
2858
|
const tagId = "dsh-skill-hub/panel.module.css";
|
|
2814
2859
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2815
2860
|
const tag = document.createElement("style");
|
|
@@ -2822,6 +2867,7 @@ window.__ModuleLoader__.load({
|
|
|
2822
2867
|
"actions": "_6VtqdG_actions",
|
|
2823
2868
|
"actionsPadded": "_6VtqdG_actionsPadded",
|
|
2824
2869
|
"actionsTop": "_6VtqdG_actionsTop",
|
|
2870
|
+
"auditBadge": "_6VtqdG_auditBadge",
|
|
2825
2871
|
"back": "_6VtqdG_back",
|
|
2826
2872
|
"badge": "_6VtqdG_badge",
|
|
2827
2873
|
"badgeCount": "_6VtqdG_badgeCount",
|
|
@@ -2841,6 +2887,7 @@ window.__ModuleLoader__.load({
|
|
|
2841
2887
|
"diagPath": "_6VtqdG_diagPath",
|
|
2842
2888
|
"diagReason": "_6VtqdG_diagReason",
|
|
2843
2889
|
"diagRow": "_6VtqdG_diagRow",
|
|
2890
|
+
"diagRowBlock": "_6VtqdG_diagRowBlock",
|
|
2844
2891
|
"dialog": "_6VtqdG_dialog",
|
|
2845
2892
|
"dialogActions": "_6VtqdG_dialogActions",
|
|
2846
2893
|
"dialogList": "_6VtqdG_dialogList",
|
|
@@ -2922,6 +2969,7 @@ window.__ModuleLoader__.load({
|
|
|
2922
2969
|
"statusBadges": "_6VtqdG_statusBadges",
|
|
2923
2970
|
"statusButton": "_6VtqdG_statusButton",
|
|
2924
2971
|
"statusError": "_6VtqdG_statusError",
|
|
2972
|
+
"statusLocal": "_6VtqdG_statusLocal",
|
|
2925
2973
|
"statusOk": "_6VtqdG_statusOk",
|
|
2926
2974
|
"statusUpdated": "_6VtqdG_statusUpdated",
|
|
2927
2975
|
"statusWrap": "_6VtqdG_statusWrap",
|
|
@@ -2957,41 +3005,48 @@ window.__ModuleLoader__.load({
|
|
|
2957
3005
|
children: tt("source.check")
|
|
2958
3006
|
});
|
|
2959
3007
|
}
|
|
2960
|
-
const
|
|
2961
|
-
if (check.error !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3008
|
+
const items = (() => {
|
|
3009
|
+
if (check.error !== void 0) return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2962
3010
|
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusError,
|
|
2963
3011
|
children: tt("source.error")
|
|
2964
|
-
});
|
|
2965
|
-
if (check.throttled === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3012
|
+
}, "error")];
|
|
3013
|
+
if (check.throttled === true) return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2966
3014
|
className: panel_module_css_default.statusBadge,
|
|
2967
3015
|
children: tt("source.throttled")
|
|
2968
|
-
});
|
|
2969
|
-
if (check.unverified === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3016
|
+
}, "throttled")];
|
|
3017
|
+
if (check.unverified === true) return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2970
3018
|
className: panel_module_css_default.statusBadge,
|
|
2971
3019
|
children: tt("source.unverified")
|
|
2972
|
-
});
|
|
2973
|
-
if (check.changed) return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2974
|
-
className: panel_module_css_default.
|
|
2975
|
-
children:
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
}) : null]
|
|
2982
|
-
});
|
|
2983
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3020
|
+
}, "unverified")];
|
|
3021
|
+
if (check.changed) return [...check.updated.length > 0 ? [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3022
|
+
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusUpdated,
|
|
3023
|
+
children: tt("source.updated", { count: check.updated.length })
|
|
3024
|
+
}, "updated")] : [], ...check.deleted.length > 0 ? [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3025
|
+
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusError,
|
|
3026
|
+
children: tt("source.deleted", { count: check.deleted.length })
|
|
3027
|
+
}, "deleted")] : []];
|
|
3028
|
+
return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2984
3029
|
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusOk,
|
|
2985
3030
|
children: tt("source.upToDate")
|
|
2986
|
-
});
|
|
3031
|
+
}, "ok")];
|
|
2987
3032
|
})();
|
|
2988
|
-
|
|
3033
|
+
const modified = check.localModified ?? [];
|
|
3034
|
+
if (modified.length > 0) items.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3035
|
+
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusLocal,
|
|
3036
|
+
title: tt("source.localModifiedHint") + "\n" + modified.join(", "),
|
|
3037
|
+
children: tt("source.localModified", { count: modified.length })
|
|
3038
|
+
}, "local"));
|
|
3039
|
+
const combined = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3040
|
+
className: panel_module_css_default.statusBadges,
|
|
3041
|
+
children: items
|
|
3042
|
+
});
|
|
3043
|
+
if (onCheck === void 0) return combined;
|
|
2989
3044
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2990
3045
|
type: "button",
|
|
2991
3046
|
className: panel_module_css_default.statusWrap,
|
|
2992
3047
|
title: tt("source.checkHint"),
|
|
2993
3048
|
onClick: onCheck,
|
|
2994
|
-
children:
|
|
3049
|
+
children: combined
|
|
2995
3050
|
});
|
|
2996
3051
|
}
|
|
2997
3052
|
//#endregion
|
|
@@ -4338,7 +4393,8 @@ window.__ModuleLoader__.load({
|
|
|
4338
4393
|
}
|
|
4339
4394
|
/** Simple confirm dialog: title + text + optional skill list + cancel/confirm. */
|
|
4340
4395
|
function ConfirmDialog(props) {
|
|
4341
|
-
const { title, text, items, confirmLabel, danger, onCancel, onConfirm } = props;
|
|
4396
|
+
const { title, text, items, marked, confirmLabel, danger, onCancel, onConfirm } = props;
|
|
4397
|
+
const markedSet = new Set(marked ?? []);
|
|
4342
4398
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DialogShell, {
|
|
4343
4399
|
onClose: onCancel,
|
|
4344
4400
|
children: [
|
|
@@ -4352,10 +4408,14 @@ window.__ModuleLoader__.load({
|
|
|
4352
4408
|
}),
|
|
4353
4409
|
items !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
4354
4410
|
className: panel_module_css_default.dialogList,
|
|
4355
|
-
children: items.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4411
|
+
children: items.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4356
4412
|
className: panel_module_css_default.rowNameText,
|
|
4357
4413
|
children: name
|
|
4358
|
-
})
|
|
4414
|
+
}), markedSet.has(name) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4415
|
+
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusLocal,
|
|
4416
|
+
style: { marginLeft: 6 },
|
|
4417
|
+
children: tt("source.localModifiedBadge")
|
|
4418
|
+
}) : null] }, name))
|
|
4359
4419
|
}) : null,
|
|
4360
4420
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4361
4421
|
className: panel_module_css_default.dialogActions,
|
|
@@ -5349,7 +5409,7 @@ window.__ModuleLoader__.load({
|
|
|
5349
5409
|
//#endregion
|
|
5350
5410
|
//#region src/client/panel/PanelDialogs.tsx
|
|
5351
5411
|
function PanelDialogs(props) {
|
|
5352
|
-
const { conflictDialog, tags, collections, setConflictDialog, resolveConflict, confirmDialog, setConfirmDialog, runConfirmed, branchChoice, branchBusy, setBranchChoice, confirmBranchChoice, versionDialog, versionBusy, setVersionDialog, confirmVersionDialog, marketSyncDialog, syncBusy, setMarketSyncDialog, confirmMarketSync, deleteSkillDialog, setDeleteSkillDialog, runDeleteSkill, deleteGroupDialog, setDeleteGroupDialog, runDeleteGroup, confirmClearTrash, setConfirmClearTrash, clearTrash } = props;
|
|
5412
|
+
const { conflictDialog, tags, collections, setConflictDialog, resolveConflict, confirmDialog, setConfirmDialog, runConfirmed, sourceCheck, branchChoice, branchBusy, setBranchChoice, confirmBranchChoice, versionDialog, versionBusy, setVersionDialog, confirmVersionDialog, marketSyncDialog, syncBusy, setMarketSyncDialog, confirmMarketSync, deleteSkillDialog, setDeleteSkillDialog, runDeleteSkill, deleteGroupDialog, setDeleteGroupDialog, runDeleteGroup, confirmClearTrash, setConfirmClearTrash, clearTrash } = props;
|
|
5353
5413
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5354
5414
|
conflictDialog !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConflictDialog, {
|
|
5355
5415
|
dialog: conflictDialog,
|
|
@@ -5369,6 +5429,7 @@ window.__ModuleLoader__.load({
|
|
|
5369
5429
|
title: confirmDialog.kind === "sync" ? tt("source.syncConfirmTitle") : tt("source.deleteConfirmTitle"),
|
|
5370
5430
|
text: confirmDialog.kind === "sync" ? tt("source.syncConfirmText") : tt("source.deleteConfirmText"),
|
|
5371
5431
|
items: confirmDialog.skills,
|
|
5432
|
+
...confirmDialog.kind === "sync" ? { marked: sourceCheck[confirmDialog.repo]?.localModified ?? [] } : {},
|
|
5372
5433
|
confirmLabel: confirmDialog.kind === "sync" ? tt("source.sync") : tt("source.followDelete"),
|
|
5373
5434
|
danger: confirmDialog.kind === "delete",
|
|
5374
5435
|
onCancel: () => {
|
|
@@ -5479,6 +5540,169 @@ window.__ModuleLoader__.load({
|
|
|
5479
5540
|
] });
|
|
5480
5541
|
}
|
|
5481
5542
|
//#endregion
|
|
5543
|
+
//#region src/client/panel/ForeignImportDialog.tsx
|
|
5544
|
+
/**
|
|
5545
|
+
* 从其他 agent 导入:列出 Claude Code / Codex / Cursor / Gemini CLI 等技能目录里的
|
|
5546
|
+
* 技能,勾选后复制到本地可写根。
|
|
5547
|
+
*
|
|
5548
|
+
* 只读扫描 + 复制,不改动别家目录。已存在的同名技能不可选(导入会覆盖,
|
|
5549
|
+
* 那是用户在别处没预期的事)。
|
|
5550
|
+
*/
|
|
5551
|
+
/** 一个技能在一组里的稳定键(同名技能可来自不同 agent)。 */
|
|
5552
|
+
function keyOf(skill) {
|
|
5553
|
+
return skill.agent + "/" + skill.name;
|
|
5554
|
+
}
|
|
5555
|
+
function ForeignImportDialog(props) {
|
|
5556
|
+
const { api, onClose, onImported } = props;
|
|
5557
|
+
const [skills, setSkills] = (0, react.useState)(null);
|
|
5558
|
+
const [error, setError] = (0, react.useState)(null);
|
|
5559
|
+
const [selected, setSelected] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
5560
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
5561
|
+
const [message, setMessage] = (0, react.useState)(null);
|
|
5562
|
+
(0, react.useEffect)(() => {
|
|
5563
|
+
let alive = true;
|
|
5564
|
+
(async () => {
|
|
5565
|
+
try {
|
|
5566
|
+
const result = await api.listForeignSkills();
|
|
5567
|
+
if (alive) setSkills(result.skills);
|
|
5568
|
+
} catch (caught) {
|
|
5569
|
+
if (alive) setError(errorMessage(caught));
|
|
5570
|
+
}
|
|
5571
|
+
})();
|
|
5572
|
+
return () => {
|
|
5573
|
+
alive = false;
|
|
5574
|
+
};
|
|
5575
|
+
}, [api]);
|
|
5576
|
+
const toggle = (skill) => {
|
|
5577
|
+
if (skill.existing || busy) return;
|
|
5578
|
+
const next = new Set(selected);
|
|
5579
|
+
const key = keyOf(skill);
|
|
5580
|
+
if (next.has(key)) next.delete(key);
|
|
5581
|
+
else next.add(key);
|
|
5582
|
+
setSelected(next);
|
|
5583
|
+
};
|
|
5584
|
+
const run = async () => {
|
|
5585
|
+
if (selected.size === 0 || skills === null) return;
|
|
5586
|
+
setBusy(true);
|
|
5587
|
+
setError(null);
|
|
5588
|
+
setMessage(null);
|
|
5589
|
+
try {
|
|
5590
|
+
const items = skills.filter((skill) => selected.has(keyOf(skill))).map((skill) => ({
|
|
5591
|
+
agent: skill.agent,
|
|
5592
|
+
name: skill.name
|
|
5593
|
+
}));
|
|
5594
|
+
const result = await api.importForeignSkills(items);
|
|
5595
|
+
const replaced = result.replaced?.length ?? 0;
|
|
5596
|
+
if (result.failed.length > 0) {
|
|
5597
|
+
setError(result.failed.map((failure) => failure.name + ": " + failure.error).join("; "));
|
|
5598
|
+
if (result.imported.length > 0) onImported(result.imported, replaced);
|
|
5599
|
+
} else if (result.skipped.length > 0) {
|
|
5600
|
+
setMessage(tt("foreign.skipped", { count: result.skipped.length }));
|
|
5601
|
+
if (result.imported.length > 0) onImported(result.imported, replaced);
|
|
5602
|
+
} else {
|
|
5603
|
+
onImported(result.imported, replaced);
|
|
5604
|
+
onClose();
|
|
5605
|
+
}
|
|
5606
|
+
} catch (caught) {
|
|
5607
|
+
setError(errorMessage(caught));
|
|
5608
|
+
} finally {
|
|
5609
|
+
setBusy(false);
|
|
5610
|
+
}
|
|
5611
|
+
};
|
|
5612
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DialogShell, {
|
|
5613
|
+
onClose,
|
|
5614
|
+
children: [
|
|
5615
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
5616
|
+
className: panel_module_css_default.dialogTitle,
|
|
5617
|
+
children: tt("foreign.title")
|
|
5618
|
+
}),
|
|
5619
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5620
|
+
className: panel_module_css_default.dialogText,
|
|
5621
|
+
children: tt("foreign.text")
|
|
5622
|
+
}),
|
|
5623
|
+
skills === null && error === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5624
|
+
className: panel_module_css_default.dialogText,
|
|
5625
|
+
children: tt("panel.loading")
|
|
5626
|
+
}) : null,
|
|
5627
|
+
skills !== null && skills.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5628
|
+
className: panel_module_css_default.dialogText,
|
|
5629
|
+
children: tt("foreign.empty")
|
|
5630
|
+
}) : null,
|
|
5631
|
+
skills !== null && skills.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
5632
|
+
className: panel_module_css_default.dialogList,
|
|
5633
|
+
style: {
|
|
5634
|
+
maxHeight: 320,
|
|
5635
|
+
overflowY: "auto"
|
|
5636
|
+
},
|
|
5637
|
+
children: skills.map((skill) => {
|
|
5638
|
+
const key = keyOf(skill);
|
|
5639
|
+
const disabled = skill.existing || busy;
|
|
5640
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
5641
|
+
style: {
|
|
5642
|
+
display: "flex",
|
|
5643
|
+
alignItems: "center",
|
|
5644
|
+
gap: 8,
|
|
5645
|
+
cursor: disabled ? "default" : "pointer"
|
|
5646
|
+
},
|
|
5647
|
+
children: [
|
|
5648
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
5649
|
+
type: "checkbox",
|
|
5650
|
+
disabled,
|
|
5651
|
+
checked: selected.has(key),
|
|
5652
|
+
onChange: () => {
|
|
5653
|
+
toggle(skill);
|
|
5654
|
+
}
|
|
5655
|
+
}),
|
|
5656
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5657
|
+
className: panel_module_css_default.rowNameText,
|
|
5658
|
+
children: skill.name
|
|
5659
|
+
}),
|
|
5660
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5661
|
+
className: panel_module_css_default.statusBadge,
|
|
5662
|
+
children: skill.agent
|
|
5663
|
+
}),
|
|
5664
|
+
skill.existing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5665
|
+
className: panel_module_css_default.statusBadge + " " + panel_module_css_default.statusLocal,
|
|
5666
|
+
children: tt("foreign.exists")
|
|
5667
|
+
}) : null
|
|
5668
|
+
]
|
|
5669
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5670
|
+
className: panel_module_css_default.rowDesc,
|
|
5671
|
+
title: skill.description,
|
|
5672
|
+
children: skill.description
|
|
5673
|
+
})] }, key);
|
|
5674
|
+
})
|
|
5675
|
+
}) : null,
|
|
5676
|
+
message !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5677
|
+
className: panel_module_css_default.dialogText,
|
|
5678
|
+
children: message
|
|
5679
|
+
}) : null,
|
|
5680
|
+
error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5681
|
+
className: panel_module_css_default.dialogText,
|
|
5682
|
+
style: { color: "var(--hub-danger)" },
|
|
5683
|
+
children: error
|
|
5684
|
+
}) : null,
|
|
5685
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5686
|
+
className: panel_module_css_default.dialogActions,
|
|
5687
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5688
|
+
type: "button",
|
|
5689
|
+
className: panel_module_css_default.button,
|
|
5690
|
+
onClick: onClose,
|
|
5691
|
+
children: tt("form.cancel")
|
|
5692
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5693
|
+
type: "button",
|
|
5694
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.primary,
|
|
5695
|
+
disabled: selected.size === 0 || busy,
|
|
5696
|
+
onClick: () => {
|
|
5697
|
+
run();
|
|
5698
|
+
},
|
|
5699
|
+
children: busy ? tt("foreign.importing") : tt("foreign.import", { count: selected.size })
|
|
5700
|
+
})]
|
|
5701
|
+
})
|
|
5702
|
+
]
|
|
5703
|
+
});
|
|
5704
|
+
}
|
|
5705
|
+
//#endregion
|
|
5482
5706
|
//#region src/client/panel/hooks/shared.ts
|
|
5483
5707
|
/**
|
|
5484
5708
|
* 统一异步动作外壳:清错 → 执行 → 异常转错误条幅 → 收尾(忙碌开关)。
|
|
@@ -6949,7 +7173,8 @@ window.__ModuleLoader__.load({
|
|
|
6949
7173
|
syncMarketSource: marketFlow.syncMarketSource,
|
|
6950
7174
|
confirmMarketSync: marketFlow.confirmMarketSync,
|
|
6951
7175
|
updateAll: marketFlow.updateAll,
|
|
6952
|
-
create: catalogFlow.create
|
|
7176
|
+
create: catalogFlow.create,
|
|
7177
|
+
reloadCatalog: catalogFlow.load
|
|
6953
7178
|
};
|
|
6954
7179
|
}
|
|
6955
7180
|
//#endregion
|
|
@@ -6972,9 +7197,11 @@ window.__ModuleLoader__.load({
|
|
|
6972
7197
|
const hub = useSkillHub(props.api);
|
|
6973
7198
|
/** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */
|
|
6974
7199
|
const [workspaceDraft, setWorkspaceDraft] = (0, react.useState)("");
|
|
7200
|
+
/** 「从其他 Agent 导入」弹窗开合。 */
|
|
7201
|
+
const [showForeign, setShowForeign] = (0, react.useState)(false);
|
|
6975
7202
|
/** 「筛选」面板开合(来源 + 调用方式收进这里;搜索/排序/视图切换始终可见)。 */
|
|
6976
7203
|
const [filtersOpen, setFiltersOpen] = (0, react.useState)(false);
|
|
6977
|
-
const { catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc, formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search, workspace, setWorkspace, sourcesState, tagBusy, batchBusy, 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;
|
|
7204
|
+
const { catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc, formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search, workspace, setWorkspace, sourcesState, tagBusy, batchBusy, 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, reloadCatalog } = hub;
|
|
6978
7205
|
const { shortenedCount, fixingPaths, clearListFilters } = hub;
|
|
6979
7206
|
if (detail !== null) {
|
|
6980
7207
|
const disabledRecord = catalog?.disabled.find((record) => record.name === detail.name);
|
|
@@ -7194,19 +7421,39 @@ window.__ModuleLoader__.load({
|
|
|
7194
7421
|
title: tt("legend.hint"),
|
|
7195
7422
|
children: "?"
|
|
7196
7423
|
}),
|
|
7197
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
7424
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7198
7425
|
className: panel_module_css_default.actions,
|
|
7199
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7426
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7427
|
+
type: "button",
|
|
7428
|
+
className: panel_module_css_default.button,
|
|
7429
|
+
onClick: () => {
|
|
7430
|
+
setShowForeign(true);
|
|
7431
|
+
},
|
|
7432
|
+
children: tt("foreign.open")
|
|
7433
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7200
7434
|
type: "button",
|
|
7201
7435
|
className: panel_module_css_default.button + " " + panel_module_css_default.primary,
|
|
7202
7436
|
onClick: () => {
|
|
7203
7437
|
setShowForm((value) => !value);
|
|
7204
7438
|
},
|
|
7205
7439
|
children: tt("panel.new")
|
|
7206
|
-
})
|
|
7440
|
+
})]
|
|
7207
7441
|
})
|
|
7208
7442
|
]
|
|
7209
7443
|
}),
|
|
7444
|
+
showForeign ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ForeignImportDialog, {
|
|
7445
|
+
api: props.api,
|
|
7446
|
+
onClose: () => {
|
|
7447
|
+
setShowForeign(false);
|
|
7448
|
+
},
|
|
7449
|
+
onImported: (imported, replaced) => {
|
|
7450
|
+
reloadCatalog();
|
|
7451
|
+
setSuccessBanner(tt(replaced > 0 ? "foreign.importedReplacedBanner" : "foreign.importedBanner", {
|
|
7452
|
+
count: imported.length,
|
|
7453
|
+
replaced
|
|
7454
|
+
}));
|
|
7455
|
+
}
|
|
7456
|
+
}) : null,
|
|
7210
7457
|
showForm ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
7211
7458
|
className: panel_module_css_default.form,
|
|
7212
7459
|
onSubmit: (event) => {
|
|
@@ -7493,6 +7740,26 @@ window.__ModuleLoader__.load({
|
|
|
7493
7740
|
children: tt("filter.shortened", { count: shortenedCount })
|
|
7494
7741
|
}) : null]
|
|
7495
7742
|
}) : null,
|
|
7743
|
+
catalog !== null && catalog.announcement !== void 0 && catalog.announcement.skills > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7744
|
+
className: panel_module_css_default.hintLine,
|
|
7745
|
+
style: {
|
|
7746
|
+
margin: "2px 2px 0",
|
|
7747
|
+
display: "flex",
|
|
7748
|
+
gap: 8,
|
|
7749
|
+
flexWrap: "wrap"
|
|
7750
|
+
},
|
|
7751
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7752
|
+
title: tt("panel.announcementHint", { budget: catalog.announcement.budget }),
|
|
7753
|
+
children: tt("panel.announcement", {
|
|
7754
|
+
chars: catalog.announcement.chars,
|
|
7755
|
+
tokens: catalog.announcement.approxTokens,
|
|
7756
|
+
skills: catalog.announcement.skills
|
|
7757
|
+
})
|
|
7758
|
+
}), catalog.announcement.overBudget ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7759
|
+
style: { color: "var(--hub-danger)" },
|
|
7760
|
+
children: tt("panel.announcementOver", { budget: catalog.announcement.budget })
|
|
7761
|
+
}) : null]
|
|
7762
|
+
}) : null,
|
|
7496
7763
|
filtered.length === 0 && search.trim() !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7497
7764
|
className: panel_module_css_default.empty,
|
|
7498
7765
|
children: tt("panel.empty")
|
|
@@ -7545,8 +7812,8 @@ window.__ModuleLoader__.load({
|
|
|
7545
7812
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7546
7813
|
className: panel_module_css_default.sectionTitle,
|
|
7547
7814
|
children: tt("panel.diagnostics")
|
|
7548
|
-
}), catalog.diagnostics.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7549
|
-
className: panel_module_css_default.diagRow,
|
|
7815
|
+
}), catalog.diagnostics.map((entry, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7816
|
+
className: panel_module_css_default.diagRow + (entry.severity === "block" ? " " + panel_module_css_default.diagRowBlock : ""),
|
|
7550
7817
|
style: {
|
|
7551
7818
|
display: "flex",
|
|
7552
7819
|
alignItems: "flex-start",
|
|
@@ -7557,9 +7824,12 @@ window.__ModuleLoader__.load({
|
|
|
7557
7824
|
flex: 1,
|
|
7558
7825
|
minWidth: 0
|
|
7559
7826
|
},
|
|
7560
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
7827
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7561
7828
|
className: panel_module_css_default.diagPath,
|
|
7562
|
-
children: entry.
|
|
7829
|
+
children: [entry.kind === "security" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7830
|
+
className: panel_module_css_default.auditBadge,
|
|
7831
|
+
children: tt("panel.auditBadge")
|
|
7832
|
+
}) : null, entry.path]
|
|
7563
7833
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7564
7834
|
className: panel_module_css_default.diagReason,
|
|
7565
7835
|
children: entry.reason
|
|
@@ -7577,7 +7847,7 @@ window.__ModuleLoader__.load({
|
|
|
7577
7847
|
},
|
|
7578
7848
|
children: fixingPaths.has(entry.path) ? tt("diag.fixing") : tt("diag.fix")
|
|
7579
7849
|
}) : null]
|
|
7580
|
-
}, entry.path))]
|
|
7850
|
+
}, entry.path + "|" + String(index)))]
|
|
7581
7851
|
}) : null
|
|
7582
7852
|
] }) : null,
|
|
7583
7853
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelDialogs, {
|
|
@@ -7589,6 +7859,7 @@ window.__ModuleLoader__.load({
|
|
|
7589
7859
|
confirmDialog,
|
|
7590
7860
|
setConfirmDialog,
|
|
7591
7861
|
runConfirmed,
|
|
7862
|
+
sourceCheck,
|
|
7592
7863
|
branchChoice,
|
|
7593
7864
|
branchBusy,
|
|
7594
7865
|
setBranchChoice,
|